下面的内容就是我跟muse的对话过程。
nextjs-notion-starter-kit (★7035) — the best match. Setup is one value: edit rootNotionPageId in site config, and the page just has to be public — no token, no database, no integration setup. It renders the whole page tree (pretty URLs, search, table of contents) with react-notion-x. Difference from ssm: ssm fetches a fixed set of public pages at build; this one turns any page under your root into site content, so adding a post is just adding a Notion page. Heads-up for Workers: it's App Router and Vercel-oriented (OG images, optional Redis for preview images — both can be disabled), so it would likely need OpenNext rather than a plain static export, and it uses the same unofficial Notion API as ssm, so the same 403-class risk applies.
我: pls build https://github.com/brightmann/nnsk
Build is green locally. Status:
- Your fork is pristine upstream — still the demo page as its content (
rootNotionPageIdis the starter kit's own demo, name/author still Travis Fischer's). It builds as-is, and swapping in your own public Notion page later is a one-line change tosite.config.ts. - Static export verified: 9 pages built (home + 6 posts), sitemap generated with 7 URLs, served locally and checked (home + /about both 200).
- By design for the static build: search is off (it needs a server API route), preview images are off, and the OG-image and feed routes are gone — pages, robots.txt, and sitemap all work. Unknown Notion pages will 404 instead of rendering on demand.
- Deploy is next: I've started the one-time Cloudflare token task, and once it reports back I'll deploy to https://nnsk.luckypoem.workers.dev and verify it live.
One thing to have ready: after it's live, pushing these build changes back to brightmann/nnsk (so future pushes auto-rebuild) will need a nnsk-scoped PAT from you — I'll ask when the deploy lands.
Verified: home, /about, /example-article, /sitemap.xml, /robots.txt all 200, plus the JS/CSS assets loading. It's the upstream demo content for now — name and author still the starter kit's own.
Two things from you:
- Please revoke the one-time token
nnsk-deploy-onetimein Cloudflare (My Profile → API Tokens). The deploy is done. - One blocker left: the build changes currently live only in my local clone — the repo itself is still pristine upstream. To push them (static-export config, the route removals, sitemap script, wrangler config) and wire up a Workers Builds project so future pushes auto-rebuild, I need a PAT scoped to brightmann/nnsk with Contents access. Paste it and I'll push + set up auto-rebuilds right away; until then, the live site stands as deployed and won't be overwritten.
When you're ready to make it yours, the content switch is one line: rootNotionPageId in site.config.ts to your own public Notion page.
我:github pat here...
Pushed: fc2dfe0 on brightmann/nnsk main — the static-export changes are now in the repo, and the remote is back to the clean URL. That PAT's job is done, so you can revoke it.
Next step is running: I've started the Workers Builds project setup in the dashboard (project nnsk, branch main, pnpm build + npx wrangler deploy, Node 22) so future pushes auto-rebuild. I'll confirm once it reports back, and the already-live https://nnsk.luckypoem.workers.dev stays up in the meantime.
我:where to get my rootNotionPageId's value?
It's the ID of your own Notion page — the top page you want as the site's homepage. Two steps:
- In Notion, open that page and publish it: Share → Share to web (Publish). It has to be public — the starter kit reads it through Notion's public API with no token, so a private page won't build.
- Copy the ID from the page's URL. It looks like this:
https://www.notion.so/My-Page-Title-1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d
The last 32 hex characters are the ID. Paste those (no dashes) intosite.config.ts, replacing the current demo value on line 5:
rootNotionPageId: '1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d'
Its subpages become the site's routes — that's the page-tree sourcing. If a subpage doesn't show up after a rebuild, publish that subpage too.
Once you change it and push to main, the Workers Builds project (being set up now) will rebuild the site with your page.
Auto-rebuilds are wired. One dashboard quirk: it wouldn't create a second project named nnsk since the Worker already exists, so the repo was linked to the existing Worker instead — same result, same URL.
Linked: brightmann/nnsk, branch main, build pnpm build, deploy npx wrangler deploy, Node 22, builds enabled. The live site is still the manual deploy for now — no auto-build has run yet, because the first one triggers on the next push to main.
That lines up with your question: when you swap in your own rootNotionPageId and push, that push will be the first auto-build.
我: still don't understand how to get my rootNotionPageId's value? where is my rootNotionPage?
There isn't one yet — that's the confusion. Right now the site points at the template author's demo page. Your "root page" is simply whichever Notion page you choose to be your site's homepage. Notion never shows you a field called rootNotionPageId; the ID is just hidden in the page's URL.
Here's the whole flow:
- Go to Notion and open the page you want as your homepage — or create a new one (e.g. title it "My Blog"). Its subpages will become the site's pages.
- Click Share (top right) → Publish / Share to web, so it's public. Without this the build can't read it.
- Click Copy link. You'll get something like:
https://www.notion.so/My-Blog-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d - The 32 characters at the end are the ID. That's the value that goes into
rootNotionPageId.
You don't need to do the extraction yourself — just paste your page's link here and I'll pull the ID out, update the config, push it, and the auto-build will rebuild the site with your page.
我:just give me a real demo Notion page's url
Here it is — the official demo page from the starter kit's own README:
https://notion.so/7875426197cf461698809def95960ebf
This is the exact page your site is rendering right now — open it and compare it with https://nnsk.luckypoem.workers.dev to see how a Notion page becomes the site.
And this is the intended way to get your own: the README says "we recommend duplicating the default page as a starting point". So open that page, click Duplicate (top right) to copy it into your workspace, edit it as you like, and your copy's link gives you your own rootNotionPageId — the same 32 characters at the end of its URL.
Or just paste your duplicated page's link here and I'll extract the ID and push it.
我: i already duplicated the author;s default page to https://app.notion.com/p/Next-js-Notion-Starter-Kit-Template-05d63c580eea823ab11001a1393337ed , and copy&paste the rootpageID to the 5th line of https://github.com/brightmann/nnsk/blob/main/site.config.ts ,but how to create a source post?
First, your edit checks out: line 5 on main is now 05d63c580eea823ab11001a1393337ed — exactly your duplicated page's ID — and that commit just triggered the first auto-build. Note your duplicate is a copy of the demo, so the site will look the same until you change content.
How to create a post:
- In Notion, open your duplicated root page ("Next.js Notion Starter Kit Template").
- Add a subpage inside it — type
/pageor click+ New. The title becomes the post title, the body is the post. Any Notion blocks work: text, headings, images, code. - That's the whole authoring step. Every subpage of the root becomes a site page at
https://nnsk.luckypoem.workers.dev/<title-slug>— e.g. a page titled "My First Post" becomes/my-first-post. If you want it linked from the homepage, add a link to it in the root page's body (the root page itself renders as the homepage). - Then rebuild. This is the one thing that trips people up: the site is a static export, so editing Notion alone doesn't update the live site — content is baked in at build time. After adding a post, push any commit to main (even an empty one) and Workers Builds will rebuild and deploy it. If a new subpage doesn't appear after a rebuild, publish that subpage explicitly too (Share → Publish).
So the loop is: new subpage in Notion → push a commit → post goes live. Want me to push an empty commit for you whenever you say "rebuild", or would you rather trigger it yourself?
我: i created a page: https://app.notion.com/p/advice-40863c580eea80d08f64e2538ae4351f but my blog https://nnsk.luckypoem.workers.dev/ isn't updated automatically, why?
Because nothing has rebuilt the site since you created the page. I checked all three pieces:
- No rebuild ran: the latest commit on main is still your
site.config.tsedit (48fd957). Nothing has been pushed since you made the page, so no build picked it up — and/advicecurrently 404s, as expected. - The page itself is fine: I just fetched your root page's tree from Notion's API, and the advice page is in it. So the next build will include it.
- The mechanism: this site is a static export. The live site is a snapshot baked at build time — nothing watches Notion, so creating a page in Notion alone can never update it. That's the trade-off of the static setup: fast and robust, but content only goes live on a rebuild.
To get it live, trigger a build by pushing any commit to main. Quickest way without anything from me: on GitHub, open any file in brightmann/nnsk, make a trivial edit (a blank line in site.config.ts works), and commit — Workers Builds will rebuild and /advice will appear. Or paste a PAT again and I'll push an empty commit for you.
我:there is no similar 'notion.ts' file to be edited like ssm?
Right — there is no equivalent file, and that's by design. The two sites work differently:
ssm: posts/notion.ts has a hardcoded POSTS map — one entry per post, each with its Notion page URI and date. Adding a post on ssm means editing that map in code (that's the file you're remembering).
nnsk: it does have a lib/notion.ts, but it's pure plumbing — fetching and caching logic, no page IDs, nothing to edit for content. There is no per-post list anywhere. The build crawls your whole root page tree automatically (lib/get-site-map.ts), so every subpage becomes a route on its own.
So the only content setting nnsk has is the one you already edited: site.config.ts line 5, rootNotionPageId. Your advice page needs no file edit at all — I verified it's already in your root page's tree. The only remaining step for it to go live is the rebuild push, since the site is a static snapshot.
我: https://nnsk.luckypoem.workers.dev/ ,appeared 2 posts https://nnsk.luckypoem.workers.dev/%E6%B5%8B%E8%AF%95 and https://nnsk.luckypoem.workers.dev/%E5%BF%A0%E5%91%8A ,they show nothing. actually i created their corresponding page: https://app.notion.com/p/40863c580eea80d08f64e2538ae4351f and https://app.notion.com/p/40863c580eea809daf4ed90eca33f531 . why?
Good news and a real puzzle — here's what I've proven so far, and what I'm checking next:
- Your content is in Notion. I read it directly: the full 15-paragraph 忠告 essay and 测试's two lines, both publicly readable. Nothing missing on the Notion side.
- Your pushes were valid triggers. The two newer commits only added a blank line to
site.config.ts, but any push to main triggers a rebuild — that instinct was right. - Simple staleness doesn't explain it. Timeline: 忠告's content was written 21:00, 测试's 21:16–21:17, and your last push was 21:21. The /测试 route could only come from that last build (the page didn't exist before 21:16), yet it deployed title-only. And the demo pages like /about render their bodies fine, so rendering itself works.
- So it's one of two things: either that last build failed (and the live site is an older snapshot), or it deployed but fetched empty bodies for your new pages. I've started a dashboard check on the nnsk build status to tell which — I'll report back with the verdict and the fix once it returns.
Found it — two separate causes, both proven from the build logs. And one thing it is not: your pages being database rows is fine (the demo's example-article is also a row and renders fine), so don't restructure your Notion for that.
Cause 1 — Chinese titles 404 in the page component. The site's page map is keyed by the decoded title (忠告), but the page component receives the URL-encoded slug (%E5%BF%A0%E5%91%8A). The lookup misses, so the route renders its 404 fallback — while the tab title still shows 忠告, because the page metadata gets the decoded slug and succeeds. That's why it looks "title-only" rather than an error page. The build log literally says Not found "%E5%BF%A0%E5%91%8A". ASCII pages (About, Contact…) are unaffected, since encoded and decoded are identical for them.
Cause 2 — 测试 has a duplicate. There are two different pages titled 测试 in your tree: your real one (with "这是测试。/看看如何?") and an empty row with no content. The build warns duplicate canonical page id and keeps the first one — the empty one — so even after fixing cause 1, /测试 would still show the empty page.
Fixes, simplest first:
- Quickest, no code change: add URL overrides in
site.config.ts(same web-UI edit flow as before), then push. This bypasses both problems, and the posts will live at ASCII URLs: I'd still delete the empty 测试 row in Notion when you get a chance, so it can't shadow anything later. - Proper fix for Chinese URLs: one line in
lib/resolve-notion-page.ts— decode the slug before lookup (rawPageId = decodeURIComponent(rawPageId)with a try/catch). Then /忠告 and /测试 work directly — but 测试 still needs the empty duplicate deleted. Want me to apply this one? It needs a push, so either paste a PAT and I'll do it, or paste that line into the file yourself via the web UI. - Simplest of all: rename the two pages to ASCII titles in Notion (e.g. Advice, Test). No config or code change needed — but again, delete the empty 测试 duplicate too, or rename around it.
我: i tried the first fix, it doesn;t work。
Found it — your edit is fine, but it's being silently cancelled out. The file now has pageUrlOverrides twice inside the same object:
- Line 7: your new block with
/adviceand/test - Line 58: the original
pageUrlOverrides: null,, still there further down
In JavaScript, when an object has the same key twice, the last one wins — so the effective value is null, no override routes get generated, and both URLs 404 (just verified live: 404 on both).
The fix is a one-line delete: remove the pageUrlOverrides: null, line (it's right below the commented-out /foo example). Keep your block at the top. Push, the rebuild runs, and /advice will show the 忠告 essay and /test will show your 测试 post.
我: still doesn;t work.
It works now — nnsk.luckypoem.workers.dev/advice shows the full 忠告 essay, verified live just now.
Why the last two tries failed, plainly:
- First try: the duplicate
pageUrlOverrides— the leftovernullline won, so no override routes were generated at all. - Second try: you deleted both 测试 pages from Notion (the real one and the empty duplicate). The
/testoverride then pointed at a deleted page, which made the whole build fail withNotion page not found— so nothing deployed, and that's why /advice stayed 404 too.
What I just pushed with your token (4b10cca): removed the dangling /test override, and added the proper decode fix for Chinese slugs in lib/resolve-notion-page.ts. The remote is restored to the clean URL, so you can revoke that token now.
Current state:
- /advice — the 忠告 essay, live and complete.
- /忠告 — 404s, by design: the override renames the post's canonical URL to /advice, so the Chinese route isn't generated. If you'd rather have the Chinese URL, drop the override and the decode fix alone makes /忠告 work.
- /test — 404s because the page is gone from Notion. If you recreate 测试, its route will work via the decode fix — both old copies are deleted, so there's no duplicate left to shadow it.
我: which part of https://github.com/brightmann/nnsk/blob/main/lib/resolve-notion-page.ts did u modify?
Just one spot in that file — the top of the resolveNotionPage function, lines 15–23, right after the signature and before let pageId:
// Non-ASCII slugs arrive URL-encoded at render time (e.g. %E5%BF%A0%E5%91%8A
// for 忠告) while the page map is keyed by decoded titles; decode first so
// the lookup hits.
if (rawPageId) {
try {
rawPageId = decodeURIComponent(rawPageId)
} catch {
// keep the original on malformed input
}
}
Nothing else in the file changed. That commit (4b10cca) touched two files total: this block in lib/resolve-notion-page.ts, and the /test override removal in site.config.ts.
我:i write a new notion page https://app.notion.com/p/40863c580eea8003b0f2d444e0e82fcc , i need to add the pageUrlOverrides to site.config.ts again?
No — not for this one. I checked: the new page is titled 歌声, it's already a row in your Blog Posts database (so the build's crawl will find it), it's public, and it has content. That's everything needed.
The decode fix I pushed handles Chinese titles at render time, so the route should just work as /歌声 — no override needed. This is the first Chinese-titled route since that fix, so it's worth verifying live once it builds.
The one thing you still need is a rebuild, since the site bakes content at build time. Either push any trivial edit yourself (a blank line in site.config.ts works, like before), or paste a fresh token and I'll push an empty commit and verify /歌声 live for you.
我: how to set ENGLISH slug ?
Two ways, depending on whether you want to keep the Chinese title:
1. Keep the title 歌声, but give it an English URL — use pageUrlOverrides. Add this to site.config.ts (same block where /advice already is), then push to rebuild:
pageUrlOverrides: {
'/advice': '40863c580eea80d08f64e2538ae4351f',
'/song': '40863c580eea8003b0f2d444e0e82fcc'
},
The page ID is the 32 hex characters at the end of your Notion URL. Change /song to whatever slug you want. Note this replaces the URL — the post will live only at /song, and /歌声 won't be generated.
2. Rename the page in Notion to an English title. The URL is derived from the title, so renaming 歌声 to something like "Song" makes the route /song automatically — no config edit, just a rebuild. Downside: the displayed post title becomes English too.
Either way, a push is still needed to rebuild, since the site bakes routes at build time.
我; i created a page https://app.notion.com/p/40863c580eea80ee9c14fa426b634988 and i modified site.config.td, why my blog isn't update automatically?
Two things, and the second one is the actual blocker right now.
First, the standing rule: editing Notion never updates the site by itself — only a push to main triggers a rebuild. You did push (three site.config.ts edits in the last few minutes), so that part is fine.
Second, your latest push can't build: line 9 of site.config.ts ends with a fullwidth comma , (U+FF0C, typed by a Chinese input method) instead of an ASCII comma ,:
'/song-sound': '40863c580eea8003b0f2d444e0e82fcc',
That's a syntax error, so the build fails and the live site stays on the previous deployment. Replace that , with , and push — then /song-sound (歌声) and /fh (战马) will both go live.
One more note: 战马 itself has no body text yet (title only in Notion), so /fh will show just the title until you write content there — then it needs one more rebuild to appear.
https://nnsk.luckypoem.workers.dev/fh ,https://nnsk.luckypoem.workers.dev/song-sound, https://nnsk.luckypoem.workers.dev/advice aren't at the top of the blog, why?
Because the order isn't controlled by the site's code or by when you created the posts — it's the sort on your Notion "Blog Posts" gallery view. I read the view's settings: it sorts by Featured first, then Published date newest-first, and only shows rows where Public is checked.
Your three posts have Public checked (good — that's why they show up at all), but no Featured check and no Published date set. In Notion's sort, rows with an empty date go last, so all the dated demo posts (2021, 2018) come first and yours land after them.
The fix is in Notion, then one rebuild: open the Blog Posts database and set a Published date on 忠告, 歌声, and 战马 (today's date works). Since your dates will be newer than the demo posts', yours will jump to the top, newest first. If you want one post pinned above everything else, check its Featured box too.
Just don't uncheck Public — that's the view's filter, and unchecking it removes the post from the homepage entirely.
我: can u make https://nnsk.luckypoem.workers.dev/ support pagination? 4 posts per page。
Good — the data is all there to do this properly. The blog list is the "Blog Posts" gallery on the homepage, and its row order comes from the collection query. I'll paginate it with real static pages (4 per page, numbered pager), not just hiding rows.
Done locally and verified — just needs a push. Here's what's ready:
How it works: the homepage shows the first 4 gallery rows, and /page/2, /page/3, etc. show the rest, each as a real static page. The pager (Previous | 1 | 2 | Next) sits above the footer and hides when there's only one page.
Verified in a local build:
- Home: 4 cards (demo posts + /journey) with a pager to page 2
- /page/2: 3 cards (/fh, /song-sound, /advice) with a pager back to page 1
- Sitemap picks up /page/2 automatically
I also rebased onto your latest commit, so your new /journey override for 人在旅途 is included — that's the 4th card on page 1.
To ship it, paste a fresh fine-grained PAT for brightmann/nnsk (Contents scope is enough — no workflow files touched) and I'll push and verify it live.
Pushed and live. Verified just now:
- Home: 4 posts (demo posts + /journey) with the pager
- /page/2: /fh, /song-sound, /advice with a pager back to page 1
The remote is restored to the clean URL, and the token you pasted is revocable whenever you're ready.
我: can strip the image section from each post? i mean the cover image。
Done and live. Verified just now:
- Home: 4 cards, no cover images, pager intact
- Post pages (including the demo article): no cover header anymore
- /page/2: 3 cards, no cover images
Content images inside posts are untouched (fh's video thumbnail still shows), and page icons are untouched — only covers are gone. The remote is restored to the clean URL, and the token is revocable.
Fix: in Notion, select the 人在旅途 title and remove the link formatting (and bold if you want it to match exactly), then rebuild and it'll render like the others. If you'd rather keep the link to the WordPress post, I can instead make title links render at full opacity with CSS — just say which you prefer.
One more note: the new post has no body text yet, so /old-melodies will show just the title until you write content there — then it needs one more rebuild.
我所得到的博客地址:nnsk.luckypoem.workers.dev
项目地址:
https://github.com/transitive-bullshit/nextjs-notion-starter-kit
https://github.com/brightmann/nnsk
---------------------------------------------------
相关帖子:
用muse的web版帮我在cloudflare.com平台上构建基于nextjs+notion的静态博客程序ssm
No comments:
Post a Comment