diff --git a/astro.config.ts b/astro.config.ts index 5b9d3887cd2be5..c8d4f627d86dfa 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -161,6 +161,7 @@ export default defineConfig({ headingLinks: false, }, routeMiddleware: "./src/plugins/starlight/route-data.ts", + disable404Route: true, }), liveCode({}), icon(), diff --git a/src/components/404.astro b/src/components/404.astro new file mode 100644 index 00000000000000..ebf99b94429785 --- /dev/null +++ b/src/components/404.astro @@ -0,0 +1,21 @@ +
+

404

+

+ Check the URL, try using our search or try our LLM-friendly + llms.txt directory. +

+
+ + diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 00000000000000..edd7cffb57d01d --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,21 @@ +--- +import StarlightPage, { + type StarlightPageProps, +} from "@astrojs/starlight/components/StarlightPage.astro"; +import FourOhFour from "~/components/404.astro"; + +const props = { + frontmatter: { + title: "404 - Page Not Found", + template: "splash", + editUrl: false, + feedback: false, + }, + hideTitle: true, + hideBreadcrumbs: true, +} as StarlightPageProps; +--- + + + + diff --git a/src/pages/[product]/404.astro b/src/pages/[product]/404.astro new file mode 100644 index 00000000000000..2409196f7aefc3 --- /dev/null +++ b/src/pages/[product]/404.astro @@ -0,0 +1,38 @@ +--- +import StarlightPage, { + type StarlightPageProps, +} from "@astrojs/starlight/components/StarlightPage.astro"; +import type { GetStaticPaths } from "astro"; +import { getCollection } from "astro:content"; + +import FourOhFour from "~/components/404.astro"; + +export const getStaticPaths = (async () => { + const sections = await getCollection("docs", (e) => { + return e.id.split("/").length === 1; + }); + + return sections.map((section) => { + return { + params: { + product: section.id, + }, + }; + }); +}) satisfies GetStaticPaths; + +const props = { + frontmatter: { + title: "404 - Page Not Found", + tableOfContents: false, + editUrl: false, + feedback: false, + }, + hideTitle: true, + hideBreadcrumbs: true, +} as StarlightPageProps; +--- + + + + diff --git a/worker/index.ts b/worker/index.ts index 619ffc2bc94c3b..79122d669ad544 100644 --- a/worker/index.ts +++ b/worker/index.ts @@ -98,6 +98,16 @@ export default class extends WorkerEntrypoint { console.error("Unknown error", error); } - return this.env.ASSETS.fetch(request); + const response = await this.env.ASSETS.fetch(request); + + if (response.status === 404) { + const section = new URL(response.url).pathname.split("/").at(1); + + if (!section) return response; + + return this.env.ASSETS.fetch(`http://fakehost/${section}/404/`); + } + + return response; } } diff --git a/worker/index.worker.test.ts b/worker/index.worker.test.ts index dfb9996dfe11e7..45ac6a5b396f6b 100644 --- a/worker/index.worker.test.ts +++ b/worker/index.worker.test.ts @@ -24,7 +24,7 @@ describe("Cloudflare Docs", () => { const request = new Request("http://fakehost/non-existent"); const response = await SELF.fetch(request); expect(response.status).toBe(404); - expect(await response.text()).toContain("Page not found."); + expect(await response.text()).toContain("Check the URL,"); }); }); @@ -283,7 +283,7 @@ describe("Cloudflare Docs", () => { const request = new Request("http://fakehost/non-existent/index.md"); const response = await SELF.fetch(request); expect(response.status).toBe(404); - expect(await response.text()).toContain("Page not found."); + expect(await response.text()).toContain("Check the URL,"); }); });