diff --git a/docs/routing.md b/docs/routing.md index 999ee0e3..ca89c610 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -16,7 +16,7 @@ To make nested routes more useful for website visitors and easier to manage for ## 404 routes -Head Start leverages [Cloudflare's Not Found behaviour](https://developers.cloudflare.com/pages/configuration/serving-pages/#not-found-behavior), which supports different 404 pages on different routes. Cloudflare will look up the directory tree until it finds a matching 404 page. A localised [root 404 page](../src/pages/[locale]/404.astro) is provided and can be edit from the CMS. You can add more specific 404 pages on specific routes, for example a `src/pages/[locale]/products/404.astro`. +Head Start leverages [Astro's Custom 404 Error page](https://docs.astro.build/en/basics/astro-pages/#custom-404-error-page) (located in [`src/pages/404.astro`](../src/pages/404.astro)), connected to the Not Found model in DatoCMS. ## API routes diff --git a/package.json b/package.json index 64b37ba2..c138dd24 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "test:unit": "vitest run", "post": "run-s post:* --print-label", "post:download-redirects": "jiti scripts/download-redirects.ts", - "post:move-404-pages": "jiti scripts/move-404-pages.ts", "postinstall": "npx husky install" }, "dependencies": { diff --git a/scripts/move-404-pages.ts b/scripts/move-404-pages.ts deleted file mode 100644 index 733852b9..00000000 --- a/scripts/move-404-pages.ts +++ /dev/null @@ -1,42 +0,0 @@ -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -import { writeFile, readFile, unlink } from 'node:fs/promises'; -import { globby } from 'globby'; -import { defaultLocale } from '../src/lib/i18n'; -import { isPreview } from '../config/preview'; -/** - * Rewrite localised "/:locale/404/index.html" to "/:locale/404.html" so Cloudflare picks them up automatically. - * Create a default 404 page, i.e. "/404.html" from the default locale. - * See https://developers.cloudflare.com/pages/platform/serving-pages/#not-found-behavior - */ -async function move404Pages() { - // create fallback 404 page from default locale - const defaultLocale404Page = await readFile(path.join(__dirname, `../dist/${defaultLocale}/404/index.html`)); - await writeFile(path.join(__dirname, '../dist/404.html'), defaultLocale404Page); - - // rewrite localised 404 pages - const filepaths = await globby(path.join(__dirname, '../dist/**/404/index.html')); - return filepaths.map(filepath => { - return moveFile(filepath, filepath.replace('404/index.html', '404.html')); - }); -} - -async function moveFile(filepath: string, newFilepath: string ) { - const content = await readFile(filepath, 'utf8'); - - // create new file and remove old one - await writeFile(newFilepath, content, 'utf8'); - await unlink(filepath); -} - -if (isPreview) { - console.log('Preview mode, skipping 404 page creation, removing 404 function'); - // 404 function causes an error: workers.api.error.script_too_large (see #123) - // since we can do without it in preview mode, we just remove it for now: - unlink(path.join(__dirname, '../functions/[locale]/404.js')); - process.exit(0); -} else { - move404Pages().then(() => console.log('Created 404 pages')); -} diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 00000000..372748ca --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,36 @@ +--- +import type { SiteLocale } from '@lib/i18n.types'; +import type { + NotFoundPageQuery, + NotFoundPageRecord, +} from '@lib/types/datocms.d.ts'; +import { datocmsRequest } from '@lib/datocms'; +import { defaultLocale, locales } from '@lib/i18n'; +import { noIndexTag, titleTag } from '@lib/seo'; +import Layout from '@layouts/Default.astro'; +import Blocks from '@blocks/Blocks.astro'; +import type { AnyBlock } from '@blocks/Blocks'; +import query from './_404.query.graphql'; + +export const prerender = false; + +Astro.response.status = 404; + +// The Astro.params.locale is unavailabe in this route, +// so we need to extract it from the URL instead: +const url = new URL(Astro.request.url); +const pathLocale = url.pathname.split('/')[1]; +const locale = locales.includes(pathLocale as SiteLocale) + ? pathLocale + : defaultLocale; + +const { page } = (await datocmsRequest({ + query, + variables: { locale }, +})) as { page: NotFoundPageRecord }; +--- + + +

{page.title}

+ +
diff --git a/src/pages/[locale]/404.astro b/src/pages/[locale]/404.astro deleted file mode 100644 index 52f2b14b..00000000 --- a/src/pages/[locale]/404.astro +++ /dev/null @@ -1,26 +0,0 @@ ---- -import { datocmsRequest } from '@lib/datocms'; -import type { NotFoundPageQuery, NotFoundPageRecord } from '@lib/types/datocms.d.ts'; -import { locales } from '@lib/i18n'; -import { noIndexTag, titleTag } from '@lib/seo'; -import Layout from '@layouts/Default.astro'; -import Blocks from '@blocks/Blocks.astro'; -import type { AnyBlock } from '@blocks/Blocks'; -import query from './_404.query.graphql'; - -export async function getStaticPaths() { - return locales.map(locale => ({ - params: { locale } - })); -} - -const { locale } = Astro.params; -const { page } = await datocmsRequest({ query, variables: { locale } }) as { page: NotFoundPageRecord }; ---- - -

{ page.title }

- -
diff --git a/src/pages/[locale]/_404.query.graphql b/src/pages/_404.query.graphql similarity index 100% rename from src/pages/[locale]/_404.query.graphql rename to src/pages/_404.query.graphql