컨텍스트 & 훅
import {
NotionRendererProvider,
useNotionRenderer,
useNotionBlock,
} from "@noxion/notion-renderer";
렌더러는 React 컨텍스트를 사용하여 설정(레코드 맵, URL 매퍼, 컴포넌트 오버라이드, 테마 설정)을 모든 하위 블록 컴포넌트에 전달합니다. 커스텀 블록 오버라이드에서 이 컨텍스트에 접근할 수 있습니다.
NotionRendererProvider
컨텍스트 프로바이더입니다. <NotionRenderer />에서 내부적으로 사용되므로, 처음부터 커스텀 렌더러를 만들지 않는 한 직접 사용할 필요가 없습니다.
Props
interface NotionRendererProviderProps {
value: NotionRendererContextValue;
children: ReactNode;
}
사용법
import { NotionRendererProvider } from "@noxion/notion-renderer";
<NotionRendererProvider value={contextValue}>
{children}
</NotionRendererProvider>
useNotionRenderer()
블록 컴포넌트나 커스텀 오버라이드 내에서 전체 렌더러 컨텍스트에 접근합니다.
시그니처
function useNotionRenderer(): NotionRendererContextValue
반환값
전체 NotionRendererContextValue 객체. 형태는 컨텍스트 값을 참조하세요.
사용법
import { useNotionRenderer } from "@noxion/notion-renderer";
function MyCustomBlock({ block }: NotionBlockProps) {
const { recordMap, darkMode, mapImageUrl, components } = useNotionRenderer();
return (
<div className={darkMode ? "dark" : "light"}>
{/* 커스텀 렌더링 */}
</div>
);
}
<NotionRendererProvider> 내에서 렌더링되는 컴포넌트 내부에서만 호출해야 합니다. <NotionRenderer />가 모든 것을 프로바이더로 래핑하므로, 블록 컴포넌트(blockOverrides 포함)에서 안전하게 이 훅을 호출할 수 있습니다.
useNotionBlock(blockId)
recordMap에서 ID로 Notion 블록을 조회합니다. 비공식 Notion API가 때때로 반환하는 중첩된 { role, value } 래퍼를 처리합니다.
시그니처
function useNotionBlock(blockId: string): Block | undefined
매개변수
| 매개변수 | 타입 | 설명 |
|---|---|---|
blockId | string | 조회할 Notion 블록 ID |
반환값
Block | undefined — notion-types의 조회된 Block 객체, 또는 레코드 맵에 없으면 undefined.
내부 동작
비공식 Notion API는 때때로 블록 값을 다음과 같이 래핑합니다:
{
"role": "reader",
"value": { ...실제 블록 데이터... }
}
useNotionBlock()은 이를 자동으로 언래핑하여 래퍼 형식에 관계없이 내부 Block을 반환합니다.
사용법
import { useNotionBlock } from "@noxion/notion-renderer";
function MyCustomBlock({ blockId }: { blockId: string }) {
const block = useNotionBlock(blockId);
if (!block) return null;
if (!block.alive) return null;
return <div>{block.type}</div>;
}
useRendererPlugins()
컨텍스트에서 렌더러 플러그인 배열에 접근합니다.
시그니처
function useRendererPlugins(): RendererPlugin[]
반환값
RendererPlugin[] — 렌더러 컨텍스트의 플러그인 배열, 또는 설정된 플러그인이 없으면 빈 배열.
사용법
import { useRendererPlugins } from "@noxion/notion-renderer";
function MyCustomBlock({ block, blockId }: NotionBlockProps) {
const plugins = useRendererPlugins();
// 커스텀 블록 결정 로직을 위해 플러그인 사용
}
useResolvedBlockRenderer()
플러그인 오버라이드를 고려하여 특정 블록을 렌더링해야 하는 컴포넌트를 결정합니다.
시그니처
function useResolvedBlockRenderer(): (
block: Block,
blockId: string,
parent?: Block
) => BlockOverrideResult | null
반환값
플러그인이 제공하는 경우 오버라이드 결과(컴포넌트 + props)를 반환하고, 기본 렌더링의 경우 null을 반환하는 함수입니다.
사용법
import { useResolvedBlockRenderer } from "@noxion/notion-renderer";
function CustomBlockDispatch({ block, blockId }: { block: Block; blockId: string }) {
const resolveRenderer = useResolvedBlockRenderer();
const override = resolveRenderer(block, blockId);
if (override) {
const { component: Component, props } = override;
return <Component block={block} blockId={blockId} level={0} {...props} />;
}
return <DefaultBlock block={block} />;
}
컨텍스트 값
NotionRendererContextValue
interface NotionRendererContextValue {
// 전체 Notion 페이지 데이터
recordMap: ExtendedRecordMap;
// Notion 페이지 ID를 URL 경로로 매핑
// 기본값: (id) => `/${id}`
mapPageUrl: MapPageUrlFn;
// 이미지 URL 매핑 (S3 → 안정적인 프록시)
// 기본값: (url) => url
mapImageUrl: MapImageUrlFn;
// 컴포넌트 오버라이드 (Image, Link, PageLink, blockOverrides)
components: NotionComponents;
// 페이지 제목 헤더를 포함한 전체 페이지 렌더링 여부
fullPage: boolean;
// 현재 다크 모드 상태
darkMode: boolean;
// 블러업 이미지 미리보기 활성화 여부
previewImages: boolean;
// 선택적 Shiki 기반 코드 하이라이터
highlightCode?: HighlightCodeFn;
// 조회된 루트 페이지 ID
rootPageId?: string;
// 폴백 페이지 아이콘 (이모지 또는 이미지 URL)
defaultPageIcon?: string | null;
// 폴백 커버 이미지 URL
defaultPageCover?: string | null;
// 폴백 커버 수직 위치 (0–1)
defaultPageCoverPosition?: number;
// 렌더러 플러그인 배열
plugins?: RendererPlugin[];
// 블록 액션 버튼 표시 여부
showBlockActions?: boolean | ((blockType: string) => boolean);
// 이미 사용된 헤딩 ID 세트 (중복 제거용)
headingIds?: Set<string>;
}
기본 컨텍스트 값
프로바이더 외부에서 접근할 때 useNotionRenderer()는 안전한 기본값을 반환합니다:
{
recordMap: { block: {}, collection: {}, collection_view: {}, collection_query: {}, notion_user: {}, signed_urls: {} },
mapPageUrl: (id) => `/${id}`,
mapImageUrl: (url) => url,
components: {},
fullPage: true,
darkMode: false,
previewImages: false,
plugins: [],
headingIds: new Set(),
}
타입 함수 시그니처
// Notion 페이지 ID를 URL로 매핑
type MapPageUrlFn = (pageId: string) => string;
// 이미지 소스 URL 매핑 (S3/Notion URL → 안정적인 프록시로 변환)
type MapImageUrlFn = (url: string, block: Block) => string;
// 원본 코드와 언어 식별자를 받아 HTML 문자열 반환
type HighlightCodeFn = (code: string, language: string) => string;
커스텀 렌더러 만들기
NotionRendererProvider, NotionBlock, NotionBlockList를 조합하여 자체 렌더러를 만들 수 있습니다:
"use client";
import {
NotionRendererProvider,
NotionBlock,
useNotionRenderer,
} from "@noxion/notion-renderer";
import type { NotionRendererContextValue, ExtendedRecordMap } from "@noxion/notion-renderer";
function MyCustomHeader() {
const { rootPageId, recordMap } = useNotionRenderer();
// recordMap에서 페이지 제목 읽기...
return <h1 className="my-title">...</h1>;
}
export function MyRenderer({
recordMap,
rootPageId,
}: {
recordMap: ExtendedRecordMap;
rootPageId: string;
}) {
const contextValue: NotionRendererContextValue = {
recordMap,
mapPageUrl: (id) => `/posts/${id}`,
mapImageUrl: (url) => url,
components: {},
fullPage: false,
darkMode: false,
previewImages: false,
rootPageId,
};
return (
<NotionRendererProvider value={contextValue}>
<article>
<MyCustomHeader />
<NotionBlock blockId={rootPageId} level={0} />
</article>
</NotionRendererProvider>
);
}