From 454d612c7c44275c90091abbf7b203b9ef098a8c Mon Sep 17 00:00:00 2001 From: Thibaud Dauce Date: Thu, 21 May 2026 11:11:33 +0200 Subject: [PATCH 1/5] fix: pages 404 --- pages/pages/[...slug].vue | 18 ++++++---------- server/routes/nuxt-api/pages/[...slug].get.ts | 21 ++++++++++++++----- tests/pages/not-found.spec.ts | 21 +++++++++++++++++++ 3 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 tests/pages/not-found.spec.ts diff --git a/pages/pages/[...slug].vue b/pages/pages/[...slug].vue index 5c7490b9b..3dd198525 100644 --- a/pages/pages/[...slug].vue +++ b/pages/pages/[...slug].vue @@ -16,10 +16,7 @@ :status :data="data" > -
+
-
-

{{ $t('Erreur 404') }}

-

{{ $t("La page que vous recherchez est introuvable.") }}

-
@@ -49,7 +39,7 @@ import BreadcrumbItem from '~/components/Breadcrumbs/BreadcrumbItem.vue' const route = useRoute() const siteConfig = useSiteConfig() -const { data, status } = useFetch<{ +const { data, status, error } = await useFetch<{ data: { title: string description?: string @@ -58,6 +48,10 @@ const { data, status } = useFetch<{ content: string }>(`/nuxt-api/pages/${route.params.slug ? (route.params.slug as string[]).join('/') : ''}`) +if (error.value || !data.value) { + throw createError({ statusCode: 404, statusMessage: 'Page Not Found', fatal: true }) +} + const title = computed(() => data.value?.data.title) const description = computed(() => data.value?.data.description) diff --git a/server/routes/nuxt-api/pages/[...slug].get.ts b/server/routes/nuxt-api/pages/[...slug].get.ts index 02c4ff1c9..a29c28751 100644 --- a/server/routes/nuxt-api/pages/[...slug].get.ts +++ b/server/routes/nuxt-api/pages/[...slug].get.ts @@ -1,5 +1,5 @@ import matter from 'gray-matter' -import { ofetch } from 'ofetch' +import { FetchError, ofetch } from 'ofetch' /** * Get the datagouv page based on the path @@ -10,7 +10,7 @@ export default cachedEventHandler(async (event) => { const config = useRuntimeConfig() const repo = config.pagesGhRepoName if (!slug || !repo) - return new Response(null, { status: 404 }) + throw createError({ statusCode: 404, statusMessage: 'Page Not Found' }) const branch = config.pagesGhRepoBranch let rawUrl = `https://raw.githubusercontent.com/${repo}/${branch}/pages/${slug}` let ghUrl = `https://github.com/${repo}/blob/${branch}/pages/${slug}` @@ -31,9 +31,20 @@ export default cachedEventHandler(async (event) => { rawUrl = `${rawUrl}.${extension}` ghUrl = `${ghUrl}.${extension}` - const response = await ofetch(rawUrl, { - timeout: 5000, - }) + let response: string + try { + response = await ofetch(rawUrl, { + timeout: 5000, + }) + } + catch (error) { + // GitHub returns a 404 when the page does not exist: return a clean 404 + // instead of letting the error bubble up as a 500. + if (error instanceof FetchError && error.statusCode === 404) { + throw createError({ statusCode: 404, statusMessage: 'Page Not Found' }) + } + throw error + } const content = matter(response) return { ghUrl, diff --git a/tests/pages/not-found.spec.ts b/tests/pages/not-found.spec.ts new file mode 100644 index 000000000..1092346c5 --- /dev/null +++ b/tests/pages/not-found.spec.ts @@ -0,0 +1,21 @@ +import { test, expect } from '../base' + +// Non-existent slugs on /pages/ must return a clean HTTP 404 rendering the +// shared error page, not a soft 404 (HTTP 200) nor a 500. +// See https://github.com/datagouv/data.gouv.fr/issues/1932 +const notFoundCases = [ + '/pages', // empty slug + '/pages/404', // example from the issue + '/pages/this-page-does-not-exist-1932', // arbitrary missing slug +] + +test.describe('Pages not found', () => { + notFoundCases.forEach((url) => { + test(`${url} returns a clean 404`, async ({ page }) => { + const response = await page.goto(url) + expect(response?.status()).toBe(404) + await expect(page.getByRole('heading', { level: 1, name: '404' })).toBeVisible() + await expect(page.getByRole('heading', { name: 'Page non trouvée' })).toBeVisible() + }) + }) +}) From 4f00e8ac23f30ff9a64158fcb743e7dda7242df1 Mon Sep 17 00:00:00 2001 From: Thibaud Dauce Date: Thu, 21 May 2026 11:38:53 +0200 Subject: [PATCH 2/5] try to fix 404 redirects --- error.vue | 299 ++++++++++++++++--------------- middleware/clear-error.global.ts | 16 ++ pages/pages/[...slug].vue | 10 +- tests/pages/not-found.spec.ts | 15 ++ 4 files changed, 194 insertions(+), 146 deletions(-) create mode 100644 middleware/clear-error.global.ts diff --git a/error.vue b/error.vue index 39afd0580..4f292ce9d 100644 --- a/error.vue +++ b/error.vue @@ -1,160 +1,169 @@