From d5f0bb5c3f84faeb7288f14250fe6669ed55744d Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:10:52 -0600 Subject: [PATCH 1/2] fix(404): resolve /404 route collision via Starlight content 404 Replace src/pages/404.astro (a second /404 route that collided with Starlight's built-in one, which Astro warns will become a hard error) with src/content/docs/404.mdx, Starlight's supported content-collection 404 override. The docs_404 Rudderstack tracking consumed by the weekly-404-monitor moves into a small Docs404Tracking.astro component and is preserved unchanged (event name + broken_url). Local build passes; the /404 collision warning is gone and docs_404 is present in the built 404.html. Co-Authored-By: Oz --- src/components/Docs404Tracking.astro | 33 +++++++++++++ src/content/docs/404.mdx | 21 ++++++++ src/pages/404.astro | 74 ---------------------------- 3 files changed, 54 insertions(+), 74 deletions(-) create mode 100644 src/components/Docs404Tracking.astro create mode 100644 src/content/docs/404.mdx delete mode 100644 src/pages/404.astro diff --git a/src/components/Docs404Tracking.astro b/src/components/Docs404Tracking.astro new file mode 100644 index 000000000..d9f1bbf63 --- /dev/null +++ b/src/components/Docs404Tracking.astro @@ -0,0 +1,33 @@ +--- +/** + * Fires a Rudderstack `docs_404` track event with the originally-requested URL. + * + * This lives in a dedicated `.astro` component rather than inline in the + * `src/content/docs/404.mdx` body because MDX parses `{`/`}` as JavaScript + * expressions, which would break the tracking IIFE. Keeping the script in an + * `.astro` file lets it pass through untouched. + * + * The `docs_404` event (and its `broken_url` property) is consumed by the + * `weekly-404-monitor` agent to surface broken docs URLs. Do not rename the + * event or drop `broken_url` without updating that skill. + */ +--- + + diff --git a/src/content/docs/404.mdx b/src/content/docs/404.mdx new file mode 100644 index 000000000..6e76c0370 --- /dev/null +++ b/src/content/docs/404.mdx @@ -0,0 +1,21 @@ +--- +title: Page not found +description: The page you are looking for does not exist or has moved. +template: splash +--- +{/* + Custom 404 page. Starlight renders the `404` docs entry through its own + prerendered /404 route (see get404Route in @astrojs/starlight), so this + replaces the previous `src/pages/404.astro` — which defined a second /404 + route and collided with Starlight's built-in one. + + The component fires the `docs_404` Rudderstack event + consumed by the weekly-404-monitor agent; keep it on this page. +*/} +import Docs404Tracking from '@components/Docs404Tracking.astro'; + +The page you are looking for does not exist or has been moved. Use the search or navigation to find what you need. + +[Go to the docs home](/) + + diff --git a/src/pages/404.astro b/src/pages/404.astro deleted file mode 100644 index 00b64a114..000000000 --- a/src/pages/404.astro +++ /dev/null @@ -1,74 +0,0 @@ ---- -/** - * Custom 404 page. - * - * Overrides Starlight's built-in 404 so we can fire a Rudderstack `docs_404` - * track event with the originally-requested URL. Without this, every 404 - * visit logs `https://docs.warp.dev/404/` — hiding which paths are actually - * broken. - * - * Uses StarlightPage so the full site chrome (nav, head, Rudderstack snippet, - * Vercel Analytics) is inherited automatically. - */ -import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; ---- - - -
-

- The page you are looking for does not exist or has been moved. Use the search or navigation - to find what you need. -

-

- Go to the docs home -

-
-
- - - - - From fb002ae0efcb533b86e95a975dd3afe575494d1a Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:23:50 -0600 Subject: [PATCH 2/2] fix: skip content-negotiation header read during prerender The content-negotiation middleware read request.headers on every route, which warned 'Astro.request.headers not available on prerendered pages' ~692x during the static build. Guard with context.isPrerendered so headers are only read for on-demand (SSR) requests; runtime markdown negotiation is unchanged. Build warnings drop from 692 to 0. Co-Authored-By: Oz --- src/middleware.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/middleware.ts b/src/middleware.ts index 537591600..e42d5f581 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -17,6 +17,14 @@ import { * negotiation and user-agent fallback detection (see `src/lib/docs-markdown.js`). */ export const onRequest = defineMiddleware(async (context, next) => { + // Content negotiation only applies to on-demand (SSR) requests. During the + // static prerender pass there is no real request, and reading + // `request.headers` warns ("not available on prerendered pages") once per + // route, which floods the build log. Skip it when the route is prerendered. + if (context.isPrerendered) { + return next(); + } + const { request, url } = context; if (!isEligibleDocHtmlPath(url.pathname)) {