Skip to content

im-ian/notion-blog

Repository files navigation

Notion Blog Project

ํ•œ๊ตญ์–ด ยท English

DEMO

  • โœ๏ธ Notion์œผ๋กœ ํฌ์ŠคํŠธ ์ž‘์„ฑ
  • โš™๏ธ ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ๋‹ค์–‘ํ•œ ์‚ฌ์ดํŠธ ์˜ต์…˜ ์„ค์ •
  • ๐ŸŽจ vanilla-extract ๊ธฐ๋ฐ˜ ํ…Œ๋งˆ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•
  • ๐Ÿ“Š Google Analytics ์ง€์›
  • ๐Ÿค– Sentry ์ง€์›

๐Ÿš€ ์‹œ์ž‘ํ•˜๊ธฐ

image

์ด ์ €์žฅ์†Œ๋ฅผ forkํ•ด์„œ ์ž‘์—… ๊ณต๊ฐ„์— cloneํ•ฉ๋‹ˆ๋‹ค.

image

Notion ํ…œํ”Œ๋ฆฟ์„ ์ž๊ธฐ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋กœ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค.

image

์ž๊ธฐ ํŽ˜์ด์ง€์˜ #f03c15 NOTION_BLOG_PAGE_ID์™€ #1589F0 NOTION_VIEW_ID๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

image

Vercel Environment Variables์— ์œ„ ๊ฐ’๋“ค์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Sentry๋กœ ์—๋Ÿฌ๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ๋‹ค์Œ 4๊ฐœ env๋ฅผ ๋ชจ๋‘ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • SENTRY_ORG
  • SENTRY_PROJECT
  • SENTRY_AUTH_TOKEN
  • SENTRY_DSN

4๊ฐœ๊ฐ€ ๋ชจ๋‘ ์žˆ์–ด์•ผ Sentry.init()์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

image

Vercel์— ๋ฐฐํฌํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค.


๐Ÿ’ป ๊ฐœ๋ฐœ

cp .env.example .env

๋กœ์ปฌ ๊ฐœ๋ฐœ์€ .env.example์„ .env๋กœ ๋ณต์‚ฌํ•œ ๋’ค ๋‹ค์Œ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

yarn && yarn dev
# ๋˜๋Š”
npm install && npm dev

๐ŸŽจ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

import type { Config } from "@/types";

const CONFIG: Config = {
  profile: {
    // ๋Œ“๊ธ€(utterances) ์—ฐ๋™์šฉ owner/repo. ๋ฏธ์„ค์ • ์‹œ ๋Œ“๊ธ€ ๋น„ํ™œ์„ฑ
    repo: "im-ian/notion-blog",
    github: "im-ian",
  },
  // ...
};

site.config.ts์—์„œ ๋‹ค์Œ ๊ทธ๋ฃน์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์ž์„ธํ•œ ์˜ต์…˜์€ ์•„๋ž˜ ํ‘œ ์ฐธ๊ณ ).

  • profile
  • notion
  • meta (SEO)
  • site
  • theme
  • search
  • posts
  • comments
  • rss
  • footer

profile

ํ‚ค ํƒ€์ž… ์„ค๋ช…
name string ํ‘œ์‹œ ์ด๋ฆ„
profileImage string | undefined ์•„๋ฐ”ํƒ€ URL
bio string | undefined ํ•œ ์ค„ ์†Œ๊ฐœ
repo string | undefined utterances ์—ฐ๋™์šฉ GitHub ๋ ˆํฌ (owner/repo). ๋ฏธ์„ค์ • ์‹œ ๋Œ“๊ธ€ ๋น„ํ™œ์„ฑ
github string | undefined GitHub username
linkedin string | undefined LinkedIn URL
instagram string | undefined Instagram URL
twitter string | undefined Twitter/X URL
threads string | undefined Threads URL

notion

ํ‚ค ํƒ€์ž… ์„ค๋ช…
blogPageId string Notion DB ํŽ˜์ด์ง€ ID. NOTION_BLOG_PAGE_ID env๋กœ ์ฃผ์ž…
viewId string Notion view ID. NOTION_VIEW_ID env๋กœ ์ฃผ์ž…. URL์˜ ?v=... ๋ถ€๋ถ„
useViewIdFilter boolean true๋กœ ๋‘๋ฉด Notion view์˜ ํ•„ํ„ฐ/์ •๋ ฌ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ. ์ฝ”๋“œ ์ธก posts.useScheduled ๋ฐ status==Public ํ•„ํ„ฐ๋Š” ๋น„ํ™œ์„ฑ (view์— ์œ„์ž„). ๊ธฐ๋ณธ false

useViewIdFilter ๋™์ž‘

๊ฐ’ ๋™์ž‘
false (๊ธฐ๋ณธ) ๋ชจ๋“  ํฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ๋’ค ์ฝ”๋“œ์˜ posts.useScheduled, status==Public ๋“ฑ์œผ๋กœ ํ•„ํ„ฐ
true Notion์—์„œ ๋งŒ๋“  view์˜ ๊ฒฐ๊ณผ๋งŒ ์‚ฌ์šฉ. ์ •๋ ฌยทํ•„ํ„ฐยทhidden ์ปฌ๋Ÿผ ๋ชจ๋‘ view์— ๋”ฐ๋ฆ„. viewId๊ฐ€ ์ž˜๋ชป๋˜๋ฉด ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ fallback (์ฝ˜์†” ๊ฒฝ๊ณ  ์ถœ๋ ฅ)

view๋ฅผ ์ง์ ‘ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด:

  1. Notion์—์„œ ๋ธ”๋กœ๊ทธ DB ์šฐ์ƒ๋‹จ + โ†’ ์ƒˆ view ์ถ”๊ฐ€ (ํ•„ํ„ฐ/์ •๋ ฌ ์ž์œ  ์„ค์ •)
  2. ํ•ด๋‹น view๋ฅผ ์—ฐ ์ƒํƒœ์—์„œ URL์˜ ?v=<viewId> ๋ถ€๋ถ„ ๋ณต์‚ฌ
  3. NOTION_VIEW_ID env์— ์ €์žฅ
  4. notion.useViewIdFilter๋ฅผ true๋กœ ํ† ๊ธ€

meta

Next.js Metadata๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ›์œผ๋ฉฐ ๋‹ค์Œ ํ‚ค๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

ํ‚ค ํƒ€์ž… ์„ค๋ช…
siteUrl string | undefined ์นด๋…ผ์ปฌ ๋„๋ฉ”์ธ. sitemap, RSS, layout metadataBase์— ์‚ฌ์šฉ. ๋ฏธ์„ค์ • ์‹œ process.env.SITE_URL fallback (production์—์„  ๋‘˜ ์ค‘ ํ•˜๋‚˜ ํ•„์ˆ˜)
ogImage string | undefined ๊ธฐ๋ณธ OG ์ด๋ฏธ์ง€. ํฌ์ŠคํŠธ ์ธ๋„ค์ผ์ด ์—†์„ ๋•Œ fallback์œผ๋กœ๋„ ์‚ฌ์šฉ

site

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
lang string "ko" <html lang> ๊ฐ’
title string โ€” ์‚ฌ์ดํŠธ ํƒ€์ดํ‹€, ํ—ค๋”์— ํ‘œ์‹œ
stickyProfile boolean false ๋ฐ์Šคํฌํƒ‘ ์ขŒ์ธก ํ”„๋กœํ•„ ์„น์…˜ ์Šคํฌ๋กค ์ถ”์ข…

theme

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
mode "auto" | "light" | "dark" "auto" ์ฒซ ๋ฐฉ๋ฌธ ๊ธฐ๋ณธ ํ…Œ๋งˆ. auto๋Š” OS ์„ค์ • ์ถ”์ข…. ์‚ฌ์šฉ์ž๊ฐ€ ํ† ๊ธ€๋กœ ๋ฐ”๊พธ๋ฉด localStorage๊ฐ€ ์šฐ์„ 
showToggle boolean true ํ—ค๋”์˜ ๋‹คํฌ๋ชจ๋“œ ํ† ๊ธ€ ๋ฒ„ํŠผ ๋…ธ์ถœ. mode๋ฅผ ๊ฐ•์ œํ•˜๊ณ  ์‹ถ์„ ๋•Œ false

search

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
shortcut boolean true ๊ฒ€์ƒ‰ ๋‹จ์ถ•ํ‚ค(โŒ˜/Ctrl+K) ํ™œ์„ฑํ™”
scope "title" | "title+summary" | "all" "all" ๊ฒ€์ƒ‰ ๋งค์นญ ๋ฒ”์œ„. all์€ title + summary + tags
showInHeader boolean true ํ—ค๋” ๊ฒ€์ƒ‰ ์•„์ด์ฝ˜ ๋…ธ์ถœ (๋‹จ์ถ•ํ‚ค๋งŒ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด false)

posts

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
perPage number 10 ํŽ˜์ด์ง€๋‹น ํฌ์ŠคํŠธ ๊ฐœ์ˆ˜ (1 ๋ฏธ๋งŒ์ด๋ฉด 1๋กœ ๋ณด์ •)
paginationMode "infinite" | "numbered" "infinite" infinite๋Š” ์ธํ”ผ๋‹ˆํ‹ฐ ์Šคํฌ๋กค(๋’ค๋กœ๊ฐ€๊ธฐ ์‹œ ๋…ธ์ถœ ๊ฐœ์ˆ˜ยท์Šคํฌ๋กค ์œ„์น˜ ๋ณต์›). numbered๋Š” ์ˆซ์ž ํŽ˜์ด์ง€ + Prev/Next ๋ฒ„ํŠผ, URL์€ ?page=N
useScheduled boolean true true์ผ ๋•Œ Public ํฌ์ŠคํŠธ๊ฐ€ ์ž‘์„ฑ์ผ์„ ๋„˜์–ด์•ผ ๋ฆฌ์ŠคํŠธ์— ๋…ธ์ถœ (์˜ˆ์•ฝ ๊ฒŒ์‹œ)
showSummary boolean true ํฌ์ŠคํŠธ ์นด๋“œ์˜ summary ๋…ธ์ถœ
showPrevNext boolean true ํฌ์ŠคํŠธ ํŽ˜์ด์ง€ ํ•˜๋‹จ ์ธ์ ‘(์ด์ „/๋‹ค์Œ) ํฌ์ŠคํŠธ ๋„ค๋น„๊ฒŒ์ด์…˜
dateFormat string "YYYY๋…„ MM์›” DD์ผ" dayjs ํ† ํฐ (์˜ˆ: "YYYY-MM-DD", "YYYY/MM/DD HH:mm")
showScrollProgress boolean true ํฌ์ŠคํŠธ ํŽ˜์ด์ง€ ์ƒ๋‹จ ์Šคํฌ๋กค ์ง„ํ–‰๋ฐ”

comments

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
use boolean true utterances ๋Œ“๊ธ€ ์˜์—ญ ๋…ธ์ถœ (profile.repo ํ•„์ˆ˜)

rss

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
use boolean true /rss.xml ํ™œ์„ฑํ™”. meta.siteUrl (๋˜๋Š” SITE_URL env) ํ•„์š”. false๋ฉด 404

footer

ํ‚ค ํƒ€์ž… ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
show boolean true ์‚ฌ์ดํŠธ ์ „์—ญ footer ์˜์—ญ ๋…ธ์ถœ
text string "ยฉ ..." ํ‘œ์‹œํ•  ํ…์ŠคํŠธ
export const vars = createGlobalTheme(":root", {
  // ...
  color: {
    white: "#fff",
    black: "#333",
    darkgray: "#2f3437",

    "gray-50": "#f9fafb",
    "gray-100": "#f3f4f6",
    "gray-200": "#e5e7eb",
    "gray-300": "#d1d5db",
    "gray-400": "#9ca3af",
    "gray-500": "#6b7280",
    "gray-600": "#4b5563",
    "gray-700": "#374151",
    // ...
  },
});

์ƒ‰์ƒ์ด๋‚˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ฐ”๊พธ๋ ค๋ฉด sprinkles.css.ts ๋˜๋Š” vars.css.ts๋ฅผ ์ˆ˜์ •ํ•˜์„ธ์š”.


๐Ÿ“„ ๋ผ์ด์„ ์Šค

MIT ๋ผ์ด์„ ์Šค ํ•˜์— ๊ณต๊ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž์œ ๋กญ๊ฒŒ forkํ•ด์„œ ์ž๊ธฐ ๋ธ”๋กœ๊ทธ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

About

notion blog with app router

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors