데이터베이스 - 보드 카드 레이아웃
Notion 데이터베이스를 카드 그리드 형태로 렌더링하는 방법을 알아봅니다.
실제 동작 데모
기본 카드 뷰
페이지네이션 적용
커스텀 테마
tip
위 데모는 실제 동작하는 컴포넌트입니다. 전체 Storybook에서 더 많은 옵션을 테스트해보세요.
언제 쓰나요?
- 프로젝트/포트폴리오 목록을 예쁜 카드로 보여주고 싶을 때
- 블로그 글 목록을 썸네일 카드로 보여주고 싶을 때
- 상품/콘텐츠 갤러리를 만들고 싶을 때
완성 코드 (복사해서 바로 사용)
// app/projects/page.tsx
import { NotionDatabaseById } from '@gendive/react-notion-renderer';
export default function ProjectsPage() {
return (
<NotionDatabaseById
databaseId="2baa76221f4080f8ac12ed40f6885c72"
token={process.env.NOTION_TOKEN!}
layout="board-card"
cardOptions={{
showCover: true, // 커버 이미지 표시
columns: 3, // 한 줄에 3개
pagination: {
enabled: true, // 페이지네이션 켜기
pageSize: 9, // 한 페이지에 9개
},
}}
/>
);
}
이게 기본이에요. 아래에서 각 옵션을 자세히 설명합니다.
카드에 뭐가 표시되나요?
기본적으로 이렇게 자동으로 찾아서 표시합니다:
| 카드 영역 | 자동으로 찾는 프로퍼티 |
|---|---|
| 제목 | title 타입 프로퍼티 |
| 설명 | 첫 번째 rich_text 타입 프로퍼티 |
| 배지 | select, multi_select, status 프로퍼티들 |
| 커버 | 페이지의 커버 이미지 |
자동 추론이 마음에 안 들면 직접 지정할 수 있어요:
cardOptions={{
titleProperty: '프로젝트명', // 제목으로 쓸 프로퍼티 이름
descriptionProperty: '설명', // 설명으로 쓸 프로퍼티 이름
badgeProperties: ['상태', '태그'], // 배지로 쓸 프로퍼티들
}}
레이아웃 조정하기
한 줄에 카드 몇 개?
cardOptions={{
columns: 4, // 한 줄에 4개 (기본값: 3)
}}
카드 너비 고정하기
기본적으로 카드는 화면 너비에 맞춰 늘어납니다.
너비를 고정하고 싶다면:
cardOptions={{
fullWidth: false, // 자동 늘어남 끄기
cardWidth: 300, // 카드 너비 300px로 고정
columns: 3,
}}
| 옵션 | 설명 | 기본값 |
|---|---|---|
columns | 한 줄에 표시할 카드 개수 | 3 |
fullWidth | true: 화면에 맞춰 늘어남, false: 고정 너비 | true |
cardWidth | fullWidth: false일 때 카드 너비(px) | 280 |
커버 이미지
cardOptions={{
showCover: true, // 커버 표시 (기본값)
}}
커버를 숨기려면:
cardOptions={{
showCover: false,
}}
tip
Notion에서 페이지 커버를 설정해야 카드에 이미지가 보여요.
데이터베이스 페이지 열고 상단에서 "Add cover"를 클릭하세요.
페이지네이션 (페이지 나누기)
카드가 많을 때 한 번에 다 보여주면 스크롤이 길어지죠.
페이지네이션을 켜면 페이지 단위로 나눠서 보여줍니다.
cardOptions={{
pagination: {
enabled: true, // 페이지네이션 켜기
pageSize: 12, // 한 페이지에 12개씩
},
}}
페이지네이션 스타일 변경
버튼 디자인을 바꾸고 싶다면:
cardOptions={{
pagination: {
enabled: true,
pageSize: 12,
style: {
activeBackground: '#2563eb', // 현재 페이지 배경색 (파란색)
activeColor: '#ffffff', // 현재 페이지 글자색 (흰색)
buttonRadius: 999, // 둥글게 (원형)
},
},
}}
페이지네이션 스타일 옵션 전체
| 옵션 | 설명 |
|---|---|
buttonBackground | 버튼 배경색 |
buttonColor | 버튼 글자색 |
buttonRadius | 버튼 둥글기 (px) |
activeBackground | 현재 페이지 배경색 |
activeColor | 현재 페이지 글자색 |
buttonPadding | 버튼 안쪽 여백 |
fontSize | 글자 크기 |
카드 테마 (색상 커스터마이징)
카드 디자인을 완전히 바꾸고 싶다면 cardTheme을 사용하세요:
cardOptions={{
cardTheme: {
cardBackground: '#1a1a2e', // 카드 배경
cardBorderColor: '#16213e', // 카드 테두리
cardRadius: 16, // 카드 둥글기
titleColor: '#eee', // 제목 색
descriptionColor: '#888', // 설명 색
badgeBackground: '#0f3460', // 배지 배경
badgeColor: '#e94560', // 배지 글자
},
}}
카드 클릭 시 상세 페이지 모달로 보기
카드를 클릭하면 **모달(팝업)**로 해당 페이지 내용을 보여주고 싶다면:
1단계: API Route 만들기
// app/api/notion/page/[pageId]/route.ts
export { GET } from '@gendive/react-notion-renderer/api';
2단계: 클라이언트 컴포넌트 만들기
// components/ProjectBoard.tsx
"use client";
import { useState } from 'react';
import {
NotionDatabaseRenderer,
NotionPageModal,
type NotionDatabaseData,
} from '@gendive/react-notion-renderer';
import { fetchNotionPageClient } from '@gendive/react-notion-renderer/client';
export function ProjectBoard({ database }: { database: NotionDatabaseData }) {
const [selectedPageId, setSelectedPageId] = useState<string | null>(null);
return (
<>
{/* 카드 그리드 */}
<NotionDatabaseRenderer
database={database}
layout="board-card"
cardOptions={{
showCover: true,
columns: 3,
pagination: { enabled: true, pageSize: 9 },
}}
onRowClick={(pageId) => setSelectedPageId(pageId)}
/>
{/* 상세 모달 */}
<NotionPageModal
pageId={selectedPageId}
onClose={() => setSelectedPageId(null)}
fetchPage={fetchNotionPageClient}
/>
</>
);
}
3단계: 서버 컴포넌트에서 데이터 가져오기
// app/projects/page.tsx
import { fetchNotionDatabase } from '@gendive/react-notion-renderer';
import { ProjectBoard } from '@/components/ProjectBoard';
export default async function ProjectsPage() {
const database = await fetchNotionDatabase(
'2baa76221f4080f8ac12ed40f6885c72',
process.env.NOTION_TOKEN!,
);
return <ProjectBoard database={database} />;
}
전체 옵션 정리
cardOptions={{
// 카드 내용
titleProperty: '프로젝트명',
descriptionProperty: '설명',
badgeProperties: ['상태', '태그'],
showCover: true,
// 레이아웃
columns: 3,
fullWidth: true,
cardWidth: 280,
// 페이지네이션
pagination: {
enabled: true,
pageSize: 12,
style: { ... },
},
// 테마
cardTheme: { ... },
}}
자주 묻는 질문
Q. 배지를 숨기고 싶어요
cardOptions={{
badgeProperties: [], // 빈 배열
}}
Q. 커버가 안 보여요
- Notion에서 해당 페이지에 커버가 설정되어 있는지 확인
showCover: true인지 확인- Integration이 해당 데이터베이스에 연결되어 있는지 확인
Q. 카드 개수가 적은데 페이지네이션이 필요한가요?
카드가 10개 미만이면 pagination: { enabled: false }로 두는 게 자연스럽습니다.
30개 이상일 때 페이지네이션을 권장합니다.