Skip to main content

@noxion/notion-renderer

npm install @noxion/notion-renderer
# or
bun add @noxion/notion-renderer

A fully custom React renderer for Notion pages. It replaces react-notion-x as the rendering core for Noxion, giving complete control over markup, CSS, accessibility, and rendering behavior.

Peer dependencies: react >= 18.0.0, notion-types >= 7.0.0, notion-utils >= 7.0.0

Optional peer dependencies: mermaid (for Mermaid plugin), chart.js (for Chart plugin)


Why a custom renderer?

react-notion-x is a capable library but couples rendering and styling tightly — hard to override CSS, no server-side KaTeX, no built-in Shiki, no tree-shakeable block components. @noxion/notion-renderer was built to solve all of this:

Featurereact-notion-x@noxion/notion-renderer
Block coverage✅ 30+ block types
KaTeX renderingClient-side only✅ SSR via katex.renderToString()
Syntax highlightingPrism (client)✅ Shiki (dual-theme CSS vars)
CSS overrideDifficult✅ BEM + CSS custom properties
Tree shaking✅ Each block is a named export
Custom block overridesLimitedcomponents.blockOverrides
Dark modeTheme-based✅ CSS vars + darkMode prop
Plugin system✅ Render-time plugin hooks
Error boundaries✅ Per-block error isolation
Lazy loadingcreateLazyBlock with Suspense
AccessibilityBasic✅ ARIA labels, keyboard navigation

Installation & setup

1. Install

bun add @noxion/notion-renderer
# peer deps (usually already installed via @noxion/core)
bun add notion-types notion-utils react

2. Import styles

/* app/globals.css or equivalent */
@import '@noxion/notion-renderer/styles';

/* Optional: KaTeX styles for math equations */
@import '@noxion/notion-renderer/katex-css';

3. Render a page

"use client";
import { NotionRenderer } from "@noxion/notion-renderer";
import type { ExtendedRecordMap } from "notion-types";

interface Props {
recordMap: ExtendedRecordMap;
pageId: string;
}

export function MyNotionPage({ recordMap, pageId }: Props) {
return (
<NotionRenderer
recordMap={recordMap}
rootPageId={pageId}
fullPage={true}
darkMode={false}
/>
);
}

Exports

Main component

ExportDescription
<NotionRenderer />Top-level renderer — wraps NotionRendererProvider + NotionBlock

Context & hooks

ExportDescription
NotionRendererProviderReact context provider for renderer state
useNotionRenderer()Access the full renderer context
useNotionBlock(blockId)Resolve a block by ID from the record map

Block components

All 30+ block components are named exports. Use them directly or override them via components.blockOverrides. See Block Components for the full list.

ExportRenders
TextBlockParagraph / plain text
HeadingBlockH1, H2, H3 (Notion: header, sub_header, sub_sub_header)
BulletedListBlockBulleted list item
NumberedListBlockNumbered list item
ToDoBlockCheckbox / to-do item
QuoteBlockBlock quote
CalloutBlockCallout with emoji icon
DividerBlockHorizontal rule
ToggleBlockCollapsible toggle
PageBlockSub-page link
EquationBlockBlock math equation (KaTeX SSR)
CodeBlockCode block with Shiki highlighting
ImageBlockImage with caption and mapImageUrl
VideoBlockVideo embed
AudioBlockAudio embed
EmbedBlockGeneric iframe embed
BookmarkBlockRich link preview
FileBlockFile attachment
PdfBlockPDF embed
TableBlockTable
ColumnListBlockColumn layout container
ColumnBlockIndividual column
SyncedContainerBlockSynced block (original)
SyncedReferenceBlockSynced block (reference)
AliasBlockBlock alias
TableOfContentsBlockAuto table of contents
CollectionViewPlaceholderDatabase / collection view (placeholder)
CollectionViewBlockInteractive table view for Notion databases (lazy-loaded)

Inline components

ExportDescription
<Text />Rich-text renderer — handles all Notion inline decorations
<InlineEquation />Inline KaTeX math expression

Plugin system

ExportDescription
RendererPluginPlugin interface with block override, transform, and lifecycle hooks
RendererPluginFactoryType-safe factory function for creating plugins
resolveBlockRendererResolve which component renders a block (plugin override or built-in)
executeBlockTransformsRun all plugin transformBlock hooks
executeTextTransformsRun all plugin transformText hooks
applyTextTransformsApply text transforms and return ReactNode array

Built-in plugins

ExportDescription
createMermaidPluginRender Mermaid diagrams from code blocks (requires mermaid peer dep)
createChartPluginRender Chart.js charts from code blocks (requires chart.js peer dep)
createCalloutTransformPluginTransform callouts into accordions or tabs based on emoji icon
createEmbedEnhancedPluginProvider-specific enhanced embed rendering
createTextTransformPluginWikilink [[Page]] and #hashtag text transforms

New components

ExportDescription
BlockErrorBoundaryReact Error Boundary for per-block error isolation
HeadingAnchorClickable anchor link for headings
BlockActionsCopy/share action buttons for blocks
LoadingPlaceholderLoading state placeholder for lazy-loaded blocks

Utilities

ExportDescription
formatNotionDate(dateValue)Format a Notion date value to a human-readable string
unwrapBlockValue(record)Unwrap { role, value } wrapper from a Notion record
getBlockTitle(block)Extract plain text title from a block's properties
cs(...classes)Conditional className utility (like clsx)

New utilities

ExportDescription
createLazyBlockWrap React.lazy() with Suspense and error boundary for block components
generateHeadingIdGenerate stable, URL-safe heading IDs with duplicate dedup
getAriaLabelGenerate accessible labels for blocks
handleKeyboardActivationHandle Enter/Space keyboard events for interactive elements
getToggleContentIdGenerate unique ID for toggle content (aria-controls)

Shiki

ExportDescription
createShikiHighlighter(options)Create a HighlightCodeFn backed by Shiki
normalizeLanguage(language)Convert Notion language names to Shiki language IDs

Types

ExportDescription
NotionRendererPropsProps for <NotionRenderer />
NotionRendererContextValueShape of the renderer context
NotionBlockPropsProps passed to every block component
NotionComponentsComponent override map
MapPageUrlFn(pageId: string) => string
MapImageUrlFn(url: string, block: Block) => string
HighlightCodeFn(code: string, language: string) => string
ExtendedRecordMapRe-export from notion-types
BlockRe-export from notion-types
BlockTypeRe-export from notion-types
DecorationRe-export from notion-types
RendererPluginPlugin interface
RendererPluginFactoryPlugin factory type
BlockOverrideArgsArguments passed to plugin blockOverride hook
BlockOverrideResultResult from plugin blockOverride hook
TransformBlockArgsArguments passed to transformBlock hook
TransformTextArgsArguments passed to transformText hook
TextReplacementText replacement with component
TextTransformResultResult from transformText hook
PluginPriorityPlugin execution priority enum

CSS exports

Import pathContents
@noxion/notion-renderer/stylesAll block styles (BEM, CSS custom properties)
@noxion/notion-renderer/katex-cssKaTeX math stylesheet

Supported Notion block types

Notion block typeComponentNotes
textTextBlockPlain paragraph
headerHeadingBlock<h1>
sub_headerHeadingBlock<h2>
sub_sub_headerHeadingBlock<h3>
bulleted_listBulletedListBlock<li> in <ul>
numbered_listNumberedListBlock<li> in <ol>
to_doToDoBlockCheckbox
quoteQuoteBlock<blockquote>
calloutCalloutBlockCallout with icon
dividerDividerBlock<hr>
toggleToggleBlock<details><summary>
pagePageBlockSub-page link
equationEquationBlockBlock KaTeX
codeCodeBlockShiki-highlighted code
imageImageBlock<figure><img>
videoVideoBlockVideo embed
audioAudioBlockAudio embed
embedEmbedBlockGeneric iframe
gistEmbedBlockGitHub Gist
figmaEmbedBlockFigma embed
tweetEmbedBlockTwitter/X embed
mapsEmbedBlockGoogle Maps
miroEmbedBlockMiro board
codepenEmbedBlockCodePen
excalidrawEmbedBlockExcalidraw
bookmarkBookmarkBlockRich link preview
fileFileBlockFile attachment
pdfPdfBlockPDF viewer
tableTableBlockNotion table
table_rowTextBlockTable row
column_listColumnListBlockColumn layout
columnColumnBlockColumn
transclusion_containerSyncedContainerBlockSynced block (original)
transclusion_referenceSyncedReferenceBlockSynced block (reference)
aliasAliasBlockBlock alias
table_of_contentsTableOfContentsBlockTOC
collection_viewCollectionViewBlockInteractive table view (lazy-loaded)
collection_view_pageCollectionViewBlockFull-page interactive table view
breadcrumbDividerBlockBreadcrumb (renders as divider)
external_object_instanceEmbedBlockExternal object