The Notion CMS
Leverage the power of Notion for your website's content organization and creation,
with the simplicity of Ghost's Content API.
docs |
quickstart
Features
🏗️ Framework agnostic - it’s just JS.
🌲 Build a collection-based CMS tree from your Notion database.
🎚️ Leverage database structure to control your routing structure.
⚙️ Geared for Static Site Generation.
📑 Transform Notion blocks → Markdown, plaintext, and (customizable) html.
🗃️ Optimized Content Caching for super fast builds.
🧩 Plugin ready with some powerful core plugins on the way.
🦾 Tagging, filtering, path queries, and tree-walking utilities.
⌨️ Totally Typesafe.
Install
npm install @agency-kit/notion-cms
pnpm add @agency-kit/notion-cms
yarn add @agency-kit/notion-cms
Why.
Notion excels at managing content. It also has a great API and SDK. But why is it so challenging to actually leverage Notion as a CMS (Content Management System) in production?
Until recently there wasn't support for sub-pages (sub-items in a database) in Notion. So most existing Notion-as-a-cms solutions don't provide a way to leverage this new feature, which turns out to be crucial for building a collection-based CMS. Another barrier is that pulling content from Notion can be time consuming. Responses can take a few seconds at times, the API provides a lot of data to sift through, and multiple calls to different endpoints are required in order to go from CMS database to the content for each page. All of this together results in a less than excellent developer experience when using a static site generator that often makes requests on each build.
NotionCMS exists to address each of these issues and provide an excellent developer experience while using Notion as your Content Management System.
The Database Structure
In order to make use of NotionCMS, you have to subscribe to a specific database structure. Its an extremely generic design that gives you all the things you need for basic sites but lends flexibility for types of content other than the standard web page, blog post etc.
See the structure in this template this template.
Basic Usage
const myCoolCMS = new NotionCMS({
databaseId: 'e4fcd5b3-1d6a-4afd-b951-10d56ce436ad',
notionAPIKey: process.env.NOTION,
})
await myCoolCMS.pull()
console.log(myCoolCMS.routes)
console.log(myCoolCMS.data)
const postA = myCoolCMS.data['/posts']['/how-to-build-a-blog-with-notion']
const postB = myCoolCMS.data['/posts']['/how-to-use-notion-cms']
Advanced Usage
const customPlugin = () => {
return {
name: 'my-custom-plugin',
hook: 'pre-parse',
exec: (blocksOrHtml) => {
const transformedBlocksOrHtml = someXform(blocksOrHtml)
return transformedBlocksOrHtml
}
}
}
const myAdvancedCMS = new NotionCMS({
databaseId: 'e4fcd5b3-1d6a-4afd-b951-10d56ce436ad',
notionAPIKey: process.env.NOTION,
rootUrl: 'https://mycoolsite.com',
localCacheDirectory: `${process.cwd()}/localcache/`,
refreshTimeout: '1 hour',
plugins: [customPlugin()],
})
await myAdvancedCMS.pull()
See the full API reference.
Some Helper methods
myCMS.queryByPath('/full/path/to/page')
myCMS.filterSubPages('/full/path/to/page' )
myCoolCMS.rejectSubPages('/full/path/to/page' )
const tagged = myCoolCMS.getTaggedCollection(['blog', 'programming'])
myCoolCMS.walk(node => console.log(node), '/partial/path/to/start')
await myCoolCMS.asyncWalk(async node => await asynchronousFunc())
Project Stats