dev-resources.site
for different kinds of informations.
Notion for NextJS CMS
Notion has become a popular productivity tool for individuals and teams. Did you know that Notion can also serve as a backend for your web applications? In this article, weāll explore the benefits of using Notion as a backend for a Next.js application and demonstrate how to do it using the Notion API and TypeScript.
Prerequisites
Before we get started, make sure you have the following:
- A Notion account
- A Notion API key
- A Next.Js project set up with TypeScript
- The notion-client package installed
To get your Notion API key, go to your Notion integrations page, create a new integration, and copy the API key. To install the notion-client package, run the following command:
npm install notion-client
1) Create a Notion database
First, letās create a Notion database to store our blog posts. To do this, go to your Notion dashboard and create a new page. In the page properties, click the āAdd a databaseā button, and select āBlog Postsā as the database template.
This will create a database with the following properties:
- Date
- Tags
- Title
- Content Feel free to customize the properties to suit your needs.
Step 2: Fetch data from Notion
Next, letās fetch the data from Notion using the Notion API. Create a new file called notion.ts in your Next.js project, and add the following code:
import { Client } from '@notionhq/client';
const notion = new Client({ auth: process.env.NOTION_API_KEY });
export async function getBlogPosts() {
const databaseId = process.env.NOTION_DATABASE_ID;
const response = await notion.databases.query({
database_id: databaseId,
});
return response.results.map((page) => ({
id: page.id,
title: page.properties['Title'].title[0].text.content,
date: page.properties['Date'].date.start,
tags: page.properties['Tags'].multi_select.map((tag) => tag.name),
content: page.properties['Content'].rich_text[0].text.content,
}));
}
In this code, weāre creating a new Client object from the notion-client package, using the NOTION_API_KEY environment variable to authenticate. Weāre also defining a function called getBlogPosts that retrieves the blog posts from Notion. Weāre using the database_id environment variable to specify the ID of the Notion database we created earlier. Then, weāre using the databases.query method to retrieve the data from the database. The databases.query method returns an array of pages, where each page represents a blog post. Weāre mapping over the results and extracting the relevant properties (title, date, tags, and content) from each page.
Step 3: Create a Next.js API route
Next, letās create a Next.js API route to serve our blog posts. Create a new file called blog.ts in the pages/api directory, and add the following code:
import { NextApiRequest, NextApiResponse } from 'next';
import { getBlogPosts } from '../../lib/notion';
...
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const posts = await getBlogPosts();
res.status(200).json(posts);
}
This code defines a new API route that retrieves the blog posts using the getBlogPosts function we defined earlier. Weāre using the NextApiRequest and NextApiResponse types from Next.js to ensure type safety.
Step 4: Display the blog posts on the frontend
Finally, letās display the blog posts on the frontend. Create a new file called index.tsx in the pages directory, and add the following code:
import { GetStaticProps } from 'next';
import { getBlogPosts } from '../lib/notion';
export const getStaticProps: GetStaticProps = async () => {
const posts = await getBlogPosts();
return {
props: {
posts,
},
};
};
interface Post {
id: string;
title: string;
date: string;
tags: string[];
content: string;
}
interface Props {
posts: Post[];
}
export default function Home({ posts }: Props) {
return (
<div>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.date}</p>
<ul>
{post.tags.map((tag) => (
<li key={tag}>{tag}</li>
))}
</ul>
<p>{post.content}</p>
</div>
))}
</div>
);
}
In this code, weāre using the GetStaticProps function from Next.js to fetch the blog posts at build time. Weāre defining a new interface called Post to represent a single blog post, and another interface called Props to represent the props of our Home component. In the Home component, weāre using the map method to render each blog post as a div element. Weāre displaying the title, date, tags, and content of each post.
Step 5: Run the application
Thatās it! You can now run your application using the following command:
npm run dev
Featured ones: