NotroTail

How this site is built

This page is a static Astro page — not a Notion page. It lives at src/pages/contact.astro and demonstrates one of two ways to add pages to a notro-tail site.

Two types of pages

Type Where the content lives bodyClass set by
Notion fixed page Notion database (rendered via NotionMarkdownRenderer) navPages[].bodyClass in config.ts
Static Astro page This .astro file <Layout bodyClass="..."> prop directly

Per-page scoped styles

Both page types share the same styling mechanism: a CSS class on <body> lets you scope styles in global.css without affecting other pages.

.page-contact

This page — indigo gradient background, h2 in indigo, links underlined indigo

.page-about

The About Notion page — blue top border on the page, h2 gets a blue left border + tinted background

.page-privacy

The Privacy Notion page — body text is smaller and subdued

Content loading pipeline

  1. The loader() from notro calls the Notion Public API and fetches pages as Markdown.
  2. Pages are cached by last_edited_time; only changed pages are re-fetched on rebuild.
  3. Preprocessed Markdown is stored in the Astro Content Collection store.
  4. At render time, NotionMarkdownRenderer runs the full remark/rehype plugin pipeline: callouts, toggles, columns, KaTeX math, table of contents, and more.
  5. Notion pre-signed S3 image URLs are cached correctly via a custom Astro image service that strips expiring X-Amz-* query parameters.

Links