FeaturesCMS
PreviousNext

Notion

Learn how to use Notion as Content Management System in your application.

In this guide, we gonna implement a blog using Notion as a content management system.

Create a notion database

The easiest way is to import our database template.

Download the database template.

Blog Template

Import it in your Notion workspace.

Importing the blog database template in Notion

Set your Notion Connection to expose your data

Add a new integration.

In the browser, go to https://www.notion.so/profile/integrations and add a "New integration".

Configure your integration settings.

In "Configuration" tab > Capabilities we gonna need :

  • Select "Read content" only (remove the other capabilities)
  • Select "No user information" (in the "User capabilities" section)

Set the NOTION_INTEGRATION_SECRET environment variable.

Show the "Internal Integration Secret" field and copy the value.

Use the copied value to set the NOTION_INTEGRATION_SECRET environment variable.

NOTION_INTEGRATION_SECRET=your-integration-secret

Set your config file

Create a config/cms.config.ts file in your application and set the NOTION_INTEGRATION_SECRET environment variable.

config/cms.config.ts
'server-only';
 
import { parseNotionConfig } from '@kit/notion/config';
import { envs } from '~/envs';
 
export const notionConfig = parseNotionConfig({
    auth: envs().NOTION_INTEGRATION_SECRET,
    contentTypes: { // edit this object to fit your needs
        // your content types here ...
    },
});
 
PropTypeDefault
contentTypes*
Record<string, { id: string; def: AnyContentTypeDef; }>
auth*
string

Add a new content type

Connect you database

Connect you database to your previously created integration

Connecting your database to your previously created integration

Get your database source id

Getting your database source id

Set the NOTION_POSTS_DB_ID environment variable.

NOTION_POSTS_DB_ID=your-database-source-id

Set your notion definition in the config file

To let the @kit/notion package to know the nature of your database, you need to add it in the contentTypes object.

config/cms.config.ts
'server-only'; import { parseNotionConfig } from '@kit/notion/config'; import { envs } from '~/envs'; export const notionConfig = parseNotionConfig({ auth: envs().NOTION_INTEGRATION_SECRET, contentTypes: { posts: { id: envs().NOTION_POSTS_DB_ID, def: { categories: 'multi_select', language: 'select', description: 'rich_text', slug: 'rich_text', image: 'files', status: 'status', title: 'title', }, }, }, });

Use the following tool to get your notion definition.

Content type definition requirements

Some properties are using internally in the notion client from the @kit/notion package. For that reason, some properties are required and some optional allow you to implement some specific features.

Required fields

Here is the list of the required fields for a content type definition:

  • title: title
  • slug: rich_text (your slug do not must contains spaces)

Optional field

  • status: status (allow you to have a draft/published feature -> the pages will be loaded only if the status is published)

Translations

You can easily manage your translations with the @kit/notion package.

Use the language property in your notion database (alredy present our the database template)

Filter your notion content items with the active i18n language

app/blog/page.tsx
'use server'; async function BlogPage(props: BlogPageProps): Promise<React.JSX.Element> { const { t, resolvedLanguage: language } = await getServerI18n(); const blogPosts = await notionClient.getContentItems({ contentType: 'posts', filter: { language, }, sort: { by: ['createdTime'], direction: 'desc', }, pagination: { limit, offset, }, content: false, }); return ( <> {/* your page content here */} </> ); }

Environment variables

.env
NOTION_INTEGRATION_SECRET=your-integration-secret
 
# your database source id ...
NOTION_POSTS_DB_ID=your-database-source-id

How is this guide?

Last updated on 10/17/2025