Skip to Content
Examples

Examples

The repository has three example projects in examples/ . All three build the same site from one Notion database: an index page with the database as a table, and one page per row with its content. They differ in the framework.

ExampleFrameworkFetches data in
nextjs-approuter Next.js App RouterServer components, generateStaticParams, generateMetadata
nextjs-pagerouter Next.js Pages RoutergetStaticProps, getStaticPaths
astro Astro with @astrojs/reactThe frontmatter of .astro pages, getStaticPaths

Prepare a database

Create a Notion database with these properties, add a few rows with some content, and connect your integration to it (see Getting started):

PropertyType
TitleTitle
TagsMulti-select
DateDate

The names must match: the examples pass ['Title', 'Tags', 'Date'] as keys and link the Title column to /[id].

Run an example

Each example needs two variables: NOTION_TOKEN, read by Rotion, and NOTION_DATABASE_ID, read by the example’s code. The Next.js examples load them from .env.local:

cd examples/nextjs-approuter cat > .env.local <<'EOF' NOTION_TOKEN=ntn_xxxxxxxxxxxxxxxxxxxxxxxx NOTION_DATABASE_ID=668d797c76fa49349b05ad288df2d136 EOF npm install npm run dev

npm run build writes a static export into out/. The examples install rotion from npm, not from the repository; their READMEs describe how to try a local build with npm pack.

nextjs-approuter

  • app/compornents/ClientLink.tsx wraps next/link with createClientLink.
  • app/page.tsx fetches the database in a server component and renders it through a small client component around <Table>, with href: { Title: '/[id]' } and the client link.
  • app/compornents/Header.tsx is an async server component that fetches the same database again for its title; the second call is served from the cache.
  • app/[id]/page.tsx lists the rows in generateStaticParams, fetches each page with FetchPage({ page_id, last_edited_time: 'force' }) and its blocks with the page’s last_edited_time, reads the title from page.meta, and shows page.icon?.src with next/image.
  • app/layout.tsx imports rotion/style-without-dark.css.
  • next.config.ts sets output: 'export' and images.unoptimized.

The walkthrough is in App Router.

nextjs-pagerouter

  • pages/index.tsx fetches the database in getStaticProps and renders <Table> with next/link passed directly as link.
  • pages/[id].tsx returns every row from getStaticPaths with fallback: false, and in getStaticProps fetches the page and the database in parallel, then the blocks.
  • pages/_app.tsx imports rotion/style.css, so this example follows the system’s dark mode.

The walkthrough is in Pages Router.

astro

  • src/pages/index.astro fetches the database in its frontmatter and renders a React <Table> wrapper.
  • src/pages/[id].astro returns every row from getStaticPaths, and fetches each page and its blocks.
  • src/components/NotionPage.tsx wraps <Page>. The pages hydrate the React components with client:load.
  • astro.config.mjs adds the React integration and sets output: 'static'.

The Astro example reads its variables from .env through import.meta.env:

cd examples/astro cat > .env <<'EOF' NOTION_TOKEN=ntn_xxxxxxxxxxxxxxxxxxxxxxxx NOTION_DATABASE_ID=668d797c76fa49349b05ad288df2d136 EOF npm install npm run dev

Rotion itself reads NOTION_TOKEN from process.env when it is imported, and the pages copy the value there from import.meta.env. Exporting the variable in the shell that runs the build (NOTION_TOKEN=... npm run build) sets it for Rotion regardless of how Astro loads .env. The development server runs at http://localhost:4321, and npm run build writes the site into dist/.

Last updated on