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 @@
+
+
+
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,");
});
});