diff --git a/app/pages/changelog/[slug].vue b/app/pages/changelog/[slug].vue index 28cbe1e9..b56f4f45 100644 --- a/app/pages/changelog/[slug].vue +++ b/app/pages/changelog/[slug].vue @@ -21,6 +21,11 @@ const slug = route.params.slug as string const { data: entry, error } = await useFetch(`/api/changelogs/${slug}`) +// Keep the not-found message, but answer 404 like the help article page does. +if (import.meta.server && error.value) { + setResponseStatus(useRequestEvent()!, 404) +} + const coverUrl = computed(() => resolveAttachmentUrl(entry.value?.cover)) const timeAgo = useTimeAgo() diff --git a/app/pages/p/[slug].vue b/app/pages/p/[slug].vue index 7e2dac5e..44df4930 100644 --- a/app/pages/p/[slug].vue +++ b/app/pages/p/[slug].vue @@ -9,7 +9,12 @@ const boardStore = useBoardStore() await callOnce(() => boardStore.fetchBoards()) // SSR: fetch via useFetch (payload auto-transferred), then hydrate store on both sides -const { data: postData } = await useFetch(`/api/posts/${slug}`) +const { data: postData, error: postError } = await useFetch(`/api/posts/${slug}`) +// A missing post is a 404, not an empty page with 200 (a "soft 404" that search +// engines index and link checkers cannot see). +if (postError.value?.statusCode === 404) { + throw createError({ statusCode: 404, statusMessage: 'Not Found', fatal: true }) +} if (postData.value) { store.setPost(slug, postData.value) }