Next.js 13 + TypeScript 기반의 개인 블로그입니다. Notion Database를 콘텐츠 소스로 사용하며, 목록은 Notion 공식 API(@notionhq/client), 상세 페이지는 react-notion-x로 렌더링합니다.
- Framework: Next.js 13.1, React 18, TypeScript
- Styling: Tailwind CSS, next-themes(다크모드)
- Content: Notion Database(@notionhq/client), notion-client, react-notion-x
- Package Manager: pnpm
pages/index.tsx: 홈. 최근 게시글 3개 노출.pages/contents/index.tsx(있는 경우): 콘텐츠 전체 목록.pages/contents/detail.tsx: Notion 페이지 상세 렌더링.pages/api/notion-page.ts: Notion 페이지 블록 fetch API.utils/notionClient.ts: Notion SDK 클라이언트 및 쿼리 유틸.components/home/*: 홈 화면 UI 컴포넌트.components/layout/*: 레이아웃 및 헤더/푸터.next.config.js: 이미지 도메인 설정 및 rewrite 설정.
/.env 또는 환경에 다음 값을 설정하세요.
NOTION_API_KEY=secret_xxx # Notion Integration 토큰
NOTION_DATABASE_ID=xxxxxxxxxxxxxxxxxxxxxx # 게시글 DB ID (하이픈 없이)
pnpm i
pnpm dev
# http://localhost:3000pnpm build
pnpm startpnpm dev: 개발 서버 실행pnpm build: 프로덕션 빌드pnpm start: 프로덕션 서버 실행pnpm lint: ESLint 실행
Notion Database에 다음 속성을 사용합니다.
- s: Title
- description: Rich text (요약)
- 날짜: Date
- tags: Multi-select
홈의 최근 글은 created_time 기준 최신 3개를 노출합니다.
react-notion-x모달은 내부적으로react-modal을 사용합니다. 앱 요소로.notion-frame을 찾으므로 상세 페이지 컨테이너에 해당 클래스를 포함합니다.Modal컴포넌트는 SSR 시 초기화 이슈를 피하기 위해next/dynamic으로 클라이언트에서만 로드합니다.
- 모달 에러: No elements were found for selector .notion-frame
- 상세 페이지 컨테이너에
.notion-frame클래스가 있어야 합니다.pages/contents/detail.tsx참고.
- 상세 페이지 컨테이너에
- 타입 오류: Notion API 결과 타입 혼합
contents.results에는 page 외 타입이 포함될 수 있습니다.pages/index.tsx에서content.object === "page"타입 가드로 필터링합니다.
- 데이터가 보이지 않음
.env의NOTION_API_KEY,NOTION_DATABASE_ID를 확인하고 Notion Integration 권한과 DB 공유가 올바른지 확인하세요.
일반적인 Vercel 배포 플로우를 따릅니다.
- 프로젝트 설정에 환경변수(
NOTION_API_KEY,NOTION_DATABASE_ID) 등록 pnpm build통과 확인 후 배포
참고:
next.config.js의images.domains와rewrites설정을 환경에 맞게 조정하세요.
Made with Next.js & Notion ✨