ReviewOS

stacks/stx

router: synchronize page head metadata after fragment navigation

#2121
Closed chris opened this 8 days ago ·
8 days ago

With the published STX and Bun plugin 0.2.687, native SPA fragment navigation updates the document title but leaves canonical and description metadata from the initial document.

Observed in Open Farming's actual Buddy server:

  1. Load / directly: title and canonical identify the homepage.
  2. Click the existing Targeted weed control link to /features/targeted-weed-control.
  3. The heading and title correctly identify Targeted weed control, while link[rel=canonical] remains https://openfarm.ing/ and the description remains the homepage description.
  4. Reload the detail URL: canonical and description correctly identify the detail page, and active navigation is correct.

The app uses ordinary native links and server-rendered layout metadata. Both installed packages match the published 0.2.687 archives, and resolution from Buddy's actual module confirms it uses those copies. This is separate from the fixed title-translation bug in #2120 and the app layout binding fix in theopenfarm/openfarm.ing#36.

Acceptance:

  • Define and implement a bounded native fragment contract for supported per-page head metadata, including canonical, description, social metadata and locale alternates.
  • Reconcile only supported metadata without replacing application assets, security tokens or unrelated head state, and preserve old-client/full-navigation compatibility.
  • Cover actual HTTP fragments and real browser navigation, back/forward, locale changes, encoded text and missing/removed metadata.
  • Fix source, release through bun run release:patch, and adopt/qualify the published dependency. No installed-package edits or distribution patches.

No claim is made that the current app PR resolves SPA head metadata. Direct-load metadata is correct, and the existing source release fixes the translated navigation title.

7 days ago

Implementation is on main: 5b45340, 28a67be, 49ef7c2, 33f2721, 016ffd9 and 043314a. The bounded inert payload covers title, description, og:/twitter: metadata, canonical and hreflang alternates; absent payloads preserve older-server behavior, while explicit empty payloads clear managed tags. Unrelated head state is not reconciled.

Regression coverage includes real HTTP and headless-browser navigation (prefetch, retained/non-retained history, locale changes, encoded/numeric/named entities, missing metadata and security-token identity), plus static/hydrated/streamed production responses. A clean registry install of 0.2.706 fails the new HTTP regression as expected. Release preflight passes locally.

v0.2.707 is prepared but NOT published. Full CI caught an island-prefetch insertion collision with literal closing-head text inside JavaScript; 63ffcdb fixes it with element-aware matching and focused regressions (50 passing). Keeping this issue open until the rerun is green and the published cohort passes the clean-installed HTTP/browser qualification. No Craft or downstream application files were changed.

7 days ago

Fixed and shipped in v0.2.707. Qualified the public-registry cohort together: @stacksjs/stx@0.2.707, bun-plugin-stx@0.2.707 and stx-router@0.2.707, installed in a clean consumer with no distribution patches.

The maintained regression packages/bun-plugin/test/serve-fragment-head.test.ts passes against that installed cohort: 4 tests, 63 assertions, zero failures. It exercises actual HTTP fragments and real headless-browser navigation, prefetch, retained/non-retained back/forward history, explicit locale switches, percent/quoted/numeric/named entity text, metadata removal, site-generated metadata, and preservation of the existing security-token node. The same clean-installed HTTP regression fails against 0.2.706 as expected.

Source production-server tests additionally cover static, hydrated and streamed fragment responses. Main CI passed with 17,193 passing tests, zero failures, plus 45 integration tests; the exact tagged release-source gate and native-signing gate also passed. Key commits: 28a67be, 49ef7c2, 33f2721, 016ffd9, 043314a; 63ffcdb fixes the island-prefetch/head-tag collision caught by full CI.

The contract deliberately reconciles only title, description, og:/twitter: metadata, canonical and hreflang alternates. Older-server fragments without the payload leave existing metadata alone; older clients leave the payload inert. This does not replace arbitrary head state. No Craft or downstream application files were changed: Buddy/Open Farming still needs to adopt the published cohort and rebuild/restart its host.

Sign in to comment on this issue.