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.

Terminal
# .env
NOTION_TOKEN=secret_abc123...
NOTION_DATABASE_ID=your-database-id

Install & Configure

Install the official Notion SDK and create a client helper to fetch content from your databases.

Terminal
# 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.

Terminal
---
// 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.