Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/n6g7/notion-cms
Notion as a headless CMS
https://github.com/n6g7/notion-cms
cms notion
Last synced: 5 days ago
JSON representation
Notion as a headless CMS
- Host: GitHub
- URL: https://github.com/n6g7/notion-cms
- Owner: n6g7
- Created: 2020-05-08T17:01:48.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-03-04T16:58:54.000Z (over 1 year ago)
- Last Synced: 2024-10-21T16:28:32.357Z (15 days ago)
- Topics: cms, notion
- Language: TypeScript
- Homepage: https://notion-cms.js.org
- Size: 2.23 MB
- Stars: 115
- Watchers: 4
- Forks: 2
- Open Issues: 22
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# notion-cms
Use [notion.so](https://www.notion.so/) as a headless CMS.
## Installation
Choose one:
- `yarn add @notion-cms/client @notion-cms/react`
- `npm install @notion-cms/client @notion-cms/react`## Usage
### Setting up a Notion integration
As of v0.1.0 notion-cms uses the official [Notion API](https://developers.notion.com/) which enables us to cleanly read data from Notion, manage access permissions, etc.
To use the Notion API we need to create a Notion integration:- Go to https://www.notion.so/my-integrations and create an integration for your project.
- If you're using Notion as a CMS typically read access will be enough (no need for insert or update capabilities). Adapt to your own needs.
- Copy the integration token.
- Share any page you need access to with the newly created integration.### Setting up a collection
The easiest way to setup your CMS data on Notion is to use [collections](https://www.notion.so/Create-a-database-2529ab92d63b478f87d39c2289527444) (aka "databases"):
![A collection on Notion.so](./docs/notion-collection.png)Use properties of any type to represent your data.
### Loading data
- The first thing you need to load your collection data is to instanciate a Notion client using the integration token from above:
```ts
import Notion from "@notion-cms/client";
export const notion = new Notion({ auth: process.env.NOTION_API_KEY });
```- Then we will setup a Typescript interface to match our collection property:
```ts
import Notion, {
DatabaseProps,
ParsedPage,
ParsedPageWithBlocks,
} from "@notion-cms/client";export type Duration =
| "Short (0-15 min)"
| "Medium (15-30 min)"
| "Long (30+ min)";
export type HealthLevel = "Indulging" | "Comforting" | "Energising";
interface RecipeProps extends DatabaseProps {
Name: string;
"Health score": HealthLevel;
"Preparation time (min)": Duration;
"Cooking time (min)": Duration;
Serves: number;
}
export interface Recipe extends ParsedPage {}
export interface RecipeWithBlocks extends ParsedPageWithBlocks {}
```The [`ParsedPage`](./packages/client/lib/types.ts) generic interface wraps the collection properties (aka props, which extend `DatabaseProps`) as well as meta data (page cover and icon).
The `ParsedPageWithBlocks` interface also contains page blocks.- Then we're going to extract the UUID of the collection we wish to load. One way to find this UUID is to run the following script in the browser console:
```js
document
.querySelectorAll(
".notion-page-content > .notion-collection_view-block"
)
.forEach((collection) =>
console.log(
collection.querySelector("[spellcheck]").textContent,
":",
collection.attributes["data-block-id"].nodeValue
)
);
```
This will print the UUIDs of all the collections in the current page.- Finally we can call the `notion.loadDatabase` method to load entries in a database (without blocks):
```ts
const recipesCollectionId = "bc0e5612-c5a1-4e3d-9d63-13bac995e5a2";const getRecipes = (): Promise =>
notion.loadDatabase(recipesCollectionId, {});
```
Or the `notion.loadPage` method to load a single page (with blocks):
```ts
const getRecipe = (recipeId: string): Promise =>
notion.loadPage(recipeId);
```### Rendering blocks
Once a Notion page has been loaded it can be easily rendered with `@notion-cms/react`:
```tsx
import { Blocks } from "@notion-cms/react";const PageComponent = ({ page }) => (
);
```