Skip to main content

Notion Setup

Noxion reads your content from Notion databases. This page explains how to set up databases for each page type, what schema properties are supported, and how to get your page IDs.


Create the database

In Notion, create a new full-page database (not an inline database). The difference matters: Noxion calls the root page to enumerate all pages, and inline databases aren't directly accessible via that page's block tree in the same way.

To create a full-page database:

  1. Create a new page
  2. Type /database and select Table — Full page

Blog database schema

Required properties

Property nameTypeRequiredDescription
TitleTitleThe post title. Every Notion database has this by default.
PublicCheckboxOnly posts where this is checked are fetched and published.
Property nameTypeDescription
PublishedDatePublication date. If absent, posts sort by last-edited time.
TagsMulti-selectPost tags. Used for tag pages (/tag/[tag]) and article:tag OG metadata.
CategorySelectPost category. Used for breadcrumbs and article:section OG metadata.
SlugText (Rich text)Custom URL slug, e.g. my-first-post. Falls back to the Notion page ID.
DescriptionText (Rich text)Meta description. Truncated at 160 characters.
AuthorText (Rich text)Author name for this specific post. Overrides the site-level author.
Case-insensitive matching

Noxion matches property names case-insensitively. public, Public, and PUBLIC all work. Extra, unknown properties are silently ignored.

Database example

┌──────────────────────────────────────────────────────────────────────────┐
│ Title │ Public │ Published │ Tags │ Category │
├──────────────────────────────────────────────────────────────────────────┤
│ My First Blog Post │ ✓ │ Jan 15 2025 │ react, next │ Web Dev │
│ Getting Started with Bun │ ✓ │ Feb 3 2025 │ bun, tooling │ Tools │
│ Draft: AI in 2025 │ │ │ ai │ │
└──────────────────────────────────────────────────────────────────────────┘

Docs database schema

For documentation sites, use these properties:

Property nameTypeRequiredDescription
TitleTitleThe page title
PublicCheckboxCheck to publish
SectionSelectRecommendedGroups docs in the sidebar (e.g. "Getting Started", "API")
OrderNumberRecommendedSort order within a section (lower = first)
SlugTextRecommendedCustom URL slug
DescriptionTextMeta description
VersionTextVersion tag (e.g. "v2", "latest")

Database example

┌───────────────────────────────────────────────────────────────────────────┐
│ Title │ Public │ Section │ Order │ Version │
├───────────────────────────────────────────────────────────────────────────┤
│ Introduction │ ✓ │ Getting Started │ 1 │ latest │
│ Installation │ ✓ │ Getting Started │ 2 │ latest │
│ Configuration │ ✓ │ API Reference │ 1 │ latest │
│ Plugin API │ ✓ │ API Reference │ 2 │ latest │
└───────────────────────────────────────────────────────────────────────────┘

The Section property is used to group pages in the sidebar navigation. Pages within a section are sorted by Order.


Portfolio database schema

For portfolio/project sites, use these properties:

Property nameTypeRequiredDescription
TitleTitleProject name
PublicCheckboxCheck to publish
TechnologiesMulti-selectRecommendedTech stack (e.g. "React", "TypeScript", "Node.js")
Project URLURL or TextLink to the live project
YearTextYear the project was built
FeaturedCheckboxMark projects to feature prominently
SlugTextRecommendedCustom URL slug
DescriptionTextMeta description

Database example

┌────────────────────────────────────────────────────────────────────────────────┐
│ Title │ Public │ Technologies │ Year │ Featured │ URL │
├────────────────────────────────────────────────────────────────────────────────┤
│ Noxion │ ✓ │ TypeScript, React │ 2026 │ ✓ │ nox.io │
│ CLI Tool │ ✓ │ Rust, CLI │ 2025 │ │ │
│ Design System │ ✓ │ React, Storybook │ 2024 │ ✓ │ ds.io │
└────────────────────────────────────────────────────────────────────────────────┘

Schema mapping

Noxion automatically maps Notion database properties to page fields using conventions per page type. You don't need to configure anything if you follow the property names above.

If your Notion database uses different property names, you can override the mapping in noxion.config.ts:

collections: [
{
databaseId: process.env.DOCS_NOTION_ID!,
pageType: "docs",
pathPrefix: "docs",
schema: {
section: "Department", // Your Notion property name → Noxion field
order: "Sort Order",
version: "Release",
},
},
],

Get the page ID

The page ID is a 32-character hexadecimal string that uniquely identifies your database page.

From the browser URL

Open your Notion database. The URL looks like:

https://notion.so/yourworkspace/Blog-abc123def456789012345678901234
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is your page ID (32 chars)

The ID may also appear with hyphens (UUID format): abc123de-f456-7890-1234-567890123456. Both formats are equivalent.

From the Share menu

  1. Open your database
  2. Click Share in the top right
  3. Click Copy link
  4. Extract the 32-char hex string from the URL

Setting the ID

For a single blog:

# .env
NOTION_PAGE_ID=abc123def456789012345678901234

For multiple databases:

# .env
NOTION_PAGE_ID=abc123... # Blog database
DOCS_NOTION_ID=def456... # Docs database
PORTFOLIO_NOTION_ID=ghi789... # Portfolio database

Private pages (optional)

By default, Noxion accesses Notion pages anonymously — the same way Notion's "Share to web" feature works. This requires your database page to be shared to web (public).

For private pages (not shared to web), you need to create a Notion integration:

Step 1: Create an integration

  1. Go to notion.so/my-integrations
  2. Click New integration
  3. Give it a name (e.g., "Noxion")
  4. Set Associated workspace to your workspace
  5. Under Capabilities, enable:
    • ✅ Read content
    • ❌ Insert content (not needed)
    • ❌ Update content (not needed)
  6. Click Submit
  7. Copy the Internal Integration Token (secret_xxx...)

Step 2: Connect the integration to your database(s)

  1. Open each Notion database you want Noxion to access
  2. Click the ... menu (top right)
  3. Click Add connections
  4. Search for and select your integration

Step 3: Add to environment variables

# .env
NOTION_TOKEN=secret_xxx...
Token security

Never commit your integration token to git. The .gitignore generated by create-noxion already excludes .env.


Writing content

Once your database is set up, creating new content is straightforward:

  1. Open your database in Notion
  2. Click New to create a new page
  3. Write your content using Notion's editor — headings, code blocks, images, embeds, callouts, etc.
  4. Fill in the database properties (Tags, Category, Description, etc.)
  5. When ready to publish, check the Public checkbox

Your content will appear on your site within:


Frontmatter overrides

Noxion reads a special code block at the very beginning of a Notion page (it must be the first content block) and treats its contents as per-page metadata overrides.

How to add frontmatter

  1. Open your page in Notion
  2. Click at the very top of the page body (before any text)
  3. Type /code and press Enter to insert a code block
  4. Type your key: value pairs

Example:

cleanUrl: /my-custom-slug
title: A Better SEO Title | My Site
description: A hand-written meta description optimized for click-through rates.

Supported keys

KeyTypeDescription
cleanUrlstringOverride the URL slug. Example: /my-post → slug becomes my-post
slugstringAlias for cleanUrl (without the leading slash)
titlestringOverride the <title> tag
descriptionstringOverride the <meta description> content
datestringOverride the publication date (YYYY-MM-DD)
categorystringOverride the category
tagsstringOverride tags (comma-separated: react, typescript, web)
coverImage / coverstringOverride the cover image URL

Any other keys are preserved in page.frontmatter as a Record<string, string> for custom use in your app.

The frontmatter code block is visible in your Notion page but hidden in the rendered output.


Supported Notion block types

Noxion uses its own block renderer (@noxion/notion-renderer) which supports 30+ Notion block types:

Block typeRendered as
Paragraph<p> with full rich text (bold, italic, code, color, links, mentions)
Heading 1/2/3<h1> / <h2> / <h3> with anchor links
Bulleted list<ul><li> with nested list support
Numbered list<ol><li> with nested list support
To-do listCheckbox list with checked/unchecked states
Toggle<details><summary> with animated expand/collapse
Quote<blockquote>
CalloutStyled callout box with emoji/icon
Code blockSyntax-highlighted via Shiki (38 languages, dual light/dark themes)
ImageOptimized via notion.so/image/ proxy URLs
Divider<hr>
TableHTML <table> with header row support
Column layoutMulti-column flex layout
EmbediFrame embed
VideoHTML5 <video> or YouTube/Vimeo embed
AudioHTML5 <audio> player
PDFEmbedded PDF viewer
FileDownload link with file metadata
BookmarkRich link card with title, description, and icon
Equation (block)Server-side KaTeX rendering (zero client JS)
Equation (inline)Inline KaTeX within rich text
MentionPage, user, date, and database mentions
Synced blocksRendered inline with source content
Table of contentsAuto-generated from page headings
Inline databases

Inline databases (collection views) inside a page are rendered as a placeholder. Full collection view support is planned for a future release.