Skip to content

Fix document title updates on SPA navigation - #805

Merged
kody-bot merged 1 commit into
mainfrom
cursor/spa-document-title-on-navigate
Jul 20, 2026
Merged

kody-bot merged 1 commit into
mainfrom
cursor/spa-document-title-on-navigate

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Jul 20, 2026 •

Copy link
Copy Markdown
Member

Summary

  • SPA navigations never updated document.title because <title> is set only during SSR outside the hydrated #root tree.
  • Added a shared route title registry (resolveDocumentTitle) and apply it from the client router on every committed navigation, including dynamic titles derived from loader data (blog posts, profiles, community packages).
  • No per-route document.title wiring — titles update automatically from one place in the navigation pipeline.

Test plan

  • Unit tests for static/dynamic/not-found title resolution
  • Typecheck
  • Related unit tests (document-title, ssr-render, client-router)
  • Pre-push e2e suite
System recap — extends existing primitives (medium risk)

Mode: recap · Base: main @ 00a5fcb4 · Head: 89f1c7e6

Classification: extends — client router now syncs document.title on SPA navigations via a shared title registry.

Primitives touched

Primitive Group Impact
app-ui surfaces extends — SPA navigation applies document titles from a shared registry
community-listings assistant composes — shell loader data includes listing name for title resolution

System map

Document titles now resolve from a shared registry at SSR fallback and on every client-router navigation commit.

Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).

flowchart LR
	appUi["app-ui<br/>Browser app (Remix 3)"]:::extended
	communityListings["community-listings<br/>Community package listings"]:::touched
	communityListings -->|"shell includes listing name"| appUi
	appUi -->|"applyDocumentTitle on nav commit"| appUi
	classDef touched fill:#1a7f37,color:#fff
	classDef extended fill:#9a6700,color:#fff
	classDef added fill:#cf222e,color:#fff
	classDef untouched fill:#57606a,color:#fff
Loading

Change flow

sequenceDiagram
	participant User
	participant Router as client-router
	participant Titles as document-title registry
	participant DOM as document.title
	User->>Router: click / navigate
	Router->>Router: run route loader
	Router->>Titles: resolveDocumentTitle(path, loaderData)
	Titles-->>Router: title string
	Router->>DOM: applyDocumentTitle
	Router->>Router: pushState + notify
Loading

Before / after

Before After
Full page load SSR <title> correct unchanged
SPA navigation document.title stuck on first page title updates from registry (+ loader data when dynamic)
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Page titles now update automatically during navigation.
    • Titles are tailored to pages such as accounts, blog posts, communities, and profiles.
    • Unknown pages display a “Not found” title.
    • Community detail pages now expose the community name for improved title handling.
  • Bug Fixes

    • Server-rendered and client-side page titles now remain consistent.

SSR set <title> once, but the client router never updated document.title
after pushState navigations. Add a shared route title registry and apply
it from the router on every committed navigation so titles stay in sync
without per-route wiring.
@kody-bot
kody-bot marked this pull request as ready for review July 20, 2026 18:06
@coderabbitai

coderabbitai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Document title synchronization

Layer / File(s) Summary
Route title registry and resolver
packages/worker/src/app/document-title.ts, packages/worker/src/app/document-title.node.test.ts, packages/worker/tsconfig-client.json
Adds route-pattern title resolution with static, loader-derived, fallback, and not-found results, plus test coverage and client compilation inclusion.
SSR title fallback and community data
packages/worker/src/app/loader-data.ts, packages/worker/src/app/handlers/community-detail.tsx, packages/worker/client/routes/community-detail.tsx, packages/worker/src/app/ssr-render.tsx
Adds the community name to shell loader data and uses resolved route titles for SSR when no explicit title is provided.
Client navigation title updates
packages/worker/client/document-title.ts, packages/worker/client/client-router.tsx
Adds browser-safe title application and updates titles after successful or failed SPA loader navigation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ClientRouter
  participant applyDocumentTitle
  participant resolveDocumentTitle
  participant BrowserDocument
  ClientRouter->>applyDocumentTitle: pathname and loader data
  applyDocumentTitle->>resolveDocumentTitle: resolve title
  resolveDocumentTitle-->>applyDocumentTitle: document title
  applyDocumentTitle->>BrowserDocument: assign document.title
Loading

Possibly related PRs

  • kentcdodds/kody#599: Introduces the community detail data flow extended here with a listing name.
  • kentcdodds/kody#608: Reworks the client-router loader navigation flow used for title updates.
  • kentcdodds/kody#800: Adds blog routes and loader data covered by the new dynamic title resolution.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing document title updates during SPA navigation.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/spa-document-title-on-navigate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-805.kody-a99.workers.dev

Worker: kody-pr-805
D1: kody-pr-805-db
KV: kody-pr-805-oauth-kv

Mocks:

@kody-bot
kody-bot merged commit 49680f3 into main Jul 20, 2026
7 checks passed
@kody-bot
kody-bot deleted the cursor/spa-document-title-on-navigate branch July 20, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants