Skip to main content

데이터베이스 - 보드 카드 레이아웃

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
fullWidthtrue: 화면에 맞춰 늘어남, false: 고정 너비true
cardWidthfullWidth: 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. 커버가 안 보여요

  1. Notion에서 해당 페이지에 커버가 설정되어 있는지 확인
  2. showCover: true인지 확인
  3. Integration이 해당 데이터베이스에 연결되어 있는지 확인

Q. 카드 개수가 적은데 페이지네이션이 필요한가요?

카드가 10개 미만이면 pagination: { enabled: false }로 두는 게 자연스럽습니다.
30개 이상일 때 페이지네이션을 권장합니다.