Notion
Use Notion as a lightweight CMS for your Astro site. Manage blog posts, changelogs, FAQs, or any structured content in Notion. Then fetch it at build time using the Notion API.
Last updated: 2026-03-29
Setup
Create a Notion integration and share your database with it. You will need the integration token and the database ID.
# .env
NOTION_TOKEN=secret_abc123...
NOTION_DATABASE_ID=your-database-idInstall & Configure
Install the official Notion SDK and create a client helper to fetch content from your databases.
# Install the SDK
npm install @notionhq/client
# src/lib/notion.js
import { Client } from "@notionhq/client";
const notion = new Client({ auth: import.meta.env.NOTION_TOKEN });
export async function getPages(databaseId) {
const response = await notion.databases.query({
database_id: databaseId,
sorts: [{ property: "Date", direction: "descending" }],
});
return response.results;
}
export async function getPageContent(pageId) {
const blocks = await notion.blocks.children.list({ block_id: pageId });
return blocks.results;
}Fetch in Astro Pages
Call your Notion helper in the frontmatter of any Astro page. Notion data is fetched at build time. No API calls at runtime, no loading spinners.
---
// src/pages/blog/index.astro
import { getPages } from "../../lib/notion";
const posts = await getPages(import.meta.env.NOTION_DATABASE_ID);
---
{posts.map((post) => (
<article>
<h2>{post.properties.Title.title[0]?.plain_text}</h2>
<p>{post.properties.Summary.rich_text[0]?.plain_text}</p>
</article>
))}Best Practices
Structure your Notion database with consistent property names and types. Use a Status property to control which pages are published.