- โ๏ธ Notion์ผ๋ก ํฌ์คํธ ์์ฑ
- โ๏ธ ์ฝ๋ ์์ ์์ด ๋ค์ํ ์ฌ์ดํธ ์ต์ ์ค์
- ๐จ vanilla-extract ๊ธฐ๋ฐ ํ ๋ง ์ปค์คํฐ๋ง์ด์ง
- ๐ Google Analytics ์ง์
- ๐ค Sentry ์ง์
์ด ์ ์ฅ์๋ฅผ forkํด์ ์์ ๊ณต๊ฐ์ cloneํฉ๋๋ค.
Notion ํ ํ๋ฆฟ์ ์๊ธฐ ์ํฌ์คํ์ด์ค๋ก ๋ณต์ ํฉ๋๋ค.
์๊ธฐ ํ์ด์ง์
NOTION_BLOG_PAGE_ID์
NOTION_VIEW_ID๋ฅผ ํ์ธํฉ๋๋ค.
Vercel Environment Variables์ ์ ๊ฐ๋ค์ ์
๋ ฅํฉ๋๋ค.
Sentry๋ก ์๋ฌ๋ฅผ ์ถ์ ํ๋ ค๋ฉด ๋ค์ 4๊ฐ env๋ฅผ ๋ชจ๋ ์ค์ ํด์ผ ํฉ๋๋ค.
SENTRY_ORGSENTRY_PROJECTSENTRY_AUTH_TOKENSENTRY_DSN
4๊ฐ๊ฐ ๋ชจ๋ ์์ด์ผ Sentry.init()์ด ํ์ฑํ๋ฉ๋๋ค.
Vercel์ ๋ฐฐํฌํ๋ฉด ๋์ ๋๋ค.
cp .env.example .env๋ก์ปฌ ๊ฐ๋ฐ์ .env.example์ .env๋ก ๋ณต์ฌํ ๋ค ๋ค์์ ์คํํฉ๋๋ค.
yarn && yarn dev
# ๋๋
npm install && npm devimport 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
| ํค | ํ์ | ์ค๋ช |
|---|---|---|
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 |
| ํค | ํ์ | ์ค๋ช |
|---|---|---|
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 |
| ๊ฐ | ๋์ |
|---|---|
false (๊ธฐ๋ณธ) |
๋ชจ๋ ํฌ์คํธ๋ฅผ ๊ฐ์ ธ์จ ๋ค ์ฝ๋์ posts.useScheduled, status==Public ๋ฑ์ผ๋ก ํํฐ |
true |
Notion์์ ๋ง๋ view์ ๊ฒฐ๊ณผ๋ง ์ฌ์ฉ. ์ ๋ ฌยทํํฐยทhidden ์ปฌ๋ผ ๋ชจ๋ view์ ๋ฐ๋ฆ. viewId๊ฐ ์๋ชป๋๋ฉด ์๋์ผ๋ก ๊ธฐ๋ณธ ๋์์ผ๋ก fallback (์ฝ์ ๊ฒฝ๊ณ ์ถ๋ ฅ) |
view๋ฅผ ์ง์ ๋ง๋ค๊ณ ์ถ๋ค๋ฉด:
- Notion์์ ๋ธ๋ก๊ทธ DB ์ฐ์๋จ
+โ ์ view ์ถ๊ฐ (ํํฐ/์ ๋ ฌ ์์ ์ค์ ) - ํด๋น view๋ฅผ ์ฐ ์ํ์์ URL์
?v=<viewId>๋ถ๋ถ ๋ณต์ฌ NOTION_VIEW_IDenv์ ์ ์ฅnotion.useViewIdFilter๋ฅผtrue๋ก ํ ๊ธ
Next.js Metadata๋ฅผ ๊ทธ๋๋ก ๋ฐ์ผ๋ฉฐ ๋ค์ ํค๊ฐ ์ถ๊ฐ๋ฉ๋๋ค.
| ํค | ํ์ | ์ค๋ช |
|---|---|---|
siteUrl |
string | undefined |
์นด๋
ผ์ปฌ ๋๋ฉ์ธ. sitemap, RSS, layout metadataBase์ ์ฌ์ฉ. ๋ฏธ์ค์ ์ process.env.SITE_URL fallback (production์์ ๋ ์ค ํ๋ ํ์) |
ogImage |
string | undefined |
๊ธฐ๋ณธ OG ์ด๋ฏธ์ง. ํฌ์คํธ ์ธ๋ค์ผ์ด ์์ ๋ fallback์ผ๋ก๋ ์ฌ์ฉ |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
lang |
string |
"ko" |
<html lang> ๊ฐ |
title |
string |
โ | ์ฌ์ดํธ ํ์ดํ, ํค๋์ ํ์ |
stickyProfile |
boolean |
false |
๋ฐ์คํฌํ ์ข์ธก ํ๋กํ ์น์ ์คํฌ๋กค ์ถ์ข |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
mode |
"auto" | "light" | "dark" |
"auto" |
์ฒซ ๋ฐฉ๋ฌธ ๊ธฐ๋ณธ ํ
๋ง. auto๋ OS ์ค์ ์ถ์ข
. ์ฌ์ฉ์๊ฐ ํ ๊ธ๋ก ๋ฐ๊พธ๋ฉด localStorage๊ฐ ์ฐ์ |
showToggle |
boolean |
true |
ํค๋์ ๋คํฌ๋ชจ๋ ํ ๊ธ ๋ฒํผ ๋
ธ์ถ. mode๋ฅผ ๊ฐ์ ํ๊ณ ์ถ์ ๋ false |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
shortcut |
boolean |
true |
๊ฒ์ ๋จ์ถํค(โ/Ctrl+K) ํ์ฑํ |
scope |
"title" | "title+summary" | "all" |
"all" |
๊ฒ์ ๋งค์นญ ๋ฒ์. all์ title + summary + tags |
showInHeader |
boolean |
true |
ํค๋ ๊ฒ์ ์์ด์ฝ ๋
ธ์ถ (๋จ์ถํค๋ง ์ฐ๊ณ ์ถ๋ค๋ฉด false) |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
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 |
ํฌ์คํธ ํ์ด์ง ์๋จ ์คํฌ๋กค ์งํ๋ฐ |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
use |
boolean |
true |
utterances ๋๊ธ ์์ญ ๋
ธ์ถ (profile.repo ํ์) |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
use |
boolean |
true |
/rss.xml ํ์ฑํ. meta.siteUrl (๋๋ SITE_URL env) ํ์. false๋ฉด 404 |
| ํค | ํ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|---|
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ํด์ ์๊ธฐ ๋ธ๋ก๊ทธ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.