The short version

This workflow uses Notion for writing, Astro for static site generation, and Cloudflare Pages for deployment. When an article is ready, press the “Publish” button in Notion to sync it to the website.

When this setup is useful

  • You already have an Astro site and want to keep its current design.

  • You prefer writing in Notion instead of editing source files for every post.

  • You want article pages, an article index, and a sitemap generated automatically.

  • You still want GitHub Markdown as a fallback or long-term archive.

How it works

Notion article → “Publish” button → Cloudflare Deploy Hook
→ Cloudflare Pages build → Astro reads Notion
→ article page / article index / articles.json / sitemap.xml

Notion is read during the Cloudflare build, not live in a visitor’s browser. The resulting site stays static and fast, and the Notion token is never exposed to readers.

Required Notion database properties

Use a full-page database with these properties:

PropertyTypePurpose
titleTitleArticle title
SlugRich textURL suffix, such as my-first-post
StatusStatusOnly pages with Published are deployed
LanguageSelectzh-CN or en; defaults to Chinese when omitted
Translation KeyRich textShared key linking a reviewed Chinese and English version

These optional properties are recommended:

PropertyTypePurpose
DateDatePublication date; page creation time is used when absent
DescriptionRich textArticle summary; the first paragraph is used when absent

Write the article body directly in the Notion page. The site creates the H1 from title, so start the body with an H2 when appropriate. Publish each language as its own Notion page. When a translation is ready, give both pages the same Translation Key; the site will connect them with a language switch and hreflang metadata.

Essential Cloudflare Pages settings

Open Settings → Variables and secrets in the Cloudflare Pages project and add these values to the Production environment:

VariableTypeValue
NOTION_TOKENSecretA Notion Internal Integration Token
NOTION_DATA_SOURCE_IDPlaintextThe Notion data source UUID
NOTION_PUBLISHED_STATUSOptional plaintextPublished; this is the default when omitted

Use NOTION_DATA_SOURCE_ID, not NOTION_DATABASE_ID. Treat both the Notion token and the Deploy Hook URL as secrets: never commit them to GitHub or include them in public posts or screenshots.

The expected build settings are:

SettingValue
Production branchmain
Build commandnpm run build
Build output directorydist

One-time setup: Deploy Hook and Notion button

  1. In Cloudflare Pages, open Settings → Build → Deploy hooks and create a hook.

  2. Name it something clear, such as notion-publish-youuc, and select the main branch.

  3. Copy the generated Webhook URL and keep it private.

  4. In the Notion database, create a Button property named “Publish”.

  5. Add these actions to the button, in order:

    • Edit property: set the current page’s Status to Published.

    • Send webhook: paste the Cloudflare Deploy Hook URL.

  6. Save the button.

One press now changes the publication state and starts a production build.

Everyday publishing workflow

  1. Create a Notion page and fill in title, Slug, and, when useful, Date and Description.

  2. Write and review the page content, formatting, and links.

  3. Press “Publish” in that article row.

  4. Wait about 30–60 seconds, then visit /articles/your-slug/.

  5. Confirm that the post also appears in the article index, /articles.json, and /sitemap.xml.

Updating or unpublishing an article

  • Update a published article: edit it in Notion, then press “Publish” again to trigger a new build.

  • Unpublish an article: change Status to anything other than Published, then trigger a deployment. The next build removes it from the site.

  • When the webhook is unavailable: manually start a Production deployment in Cloudflare Pages; it will still sync Notion content.

Using Notion and GitHub Markdown together

The site accepts two article sources:

  • GitHub Markdown: add files to content/articles/ and commit to main.

  • Notion: pages with Status = Published are synced during the build.

Both sources are merged into the same article index, homepage archive, articles.json, and sitemap.xml. Keep every Slug unique to avoid collisions.

Troubleshooting checklist

SymptomCheck first
The build succeeds but no article appearsConfirm that Production has both NOTION_TOKEN and NOTION_DATA_SOURCE_ID
The build says Notion is not configuredCheck variable names, scope, and that changes were saved
A Notion page is not syncedConfirm Status is Published and the integration has access to the data source
The article URL does not openEnsure the Slug is unique and uses only letters, numbers, and hyphens
Site content did not change after an editPress “Publish” again or trigger a manual deployment

AI summary and retrieval keywords

AI summary: This guide explains how to use Notion as the writing interface for an Astro static blog, trigger a Cloudflare Pages build with a Deploy Hook, and automatically produce article pages, an article index, a JSON index, and an XML sitemap from published Notion pages.

Keywords: Notion CMS, Notion blog, Astro Notion integration, Cloudflare Pages, Deploy Hook, static site publishing, Notion webhook, Markdown and Notion workflow, article sync, XML sitemap, SEO.

FAQ

Why do Notion edits require a new deployment?

The content is written into the static site at build time. This keeps the site fast and prevents the token from reaching visitors’ browsers.

Can I use GitHub Markdown only?

Yes. Notion is an additional visual writing interface; it does not replace the existing Markdown workflow.

Can the Deploy Hook URL be public?

No. Anyone with the URL can trigger a build, so store it like a password.