From 0848c98e6f299770c30ab52ebe6f369792e49b43 Mon Sep 17 00:00:00 2001 From: MarketDataApp <112879596+MarketDataApp@users.noreply.github.com> Date: Sat, 31 Oct 2026 10:47:10 -0400 Subject: [PATCH] fix(pages): answer 404 for a missing post or changelog entry The post page read only `data` from useFetch('/api/posts/'), so a missing post rendered an empty page with HTTP 200. The changelog entry page showed its not-found message, also with 200. Both APIs already answer 404. The post page has no not-found state, so it now throws the same fatal 404 the help article page throws when the help center is off. The changelog page keeps its message and sets the status during SSR, as the help article page does. Closes #49 Signed-off-by: MarketDataApp <112879596+MarketDataApp@users.noreply.github.com> --- app/pages/changelog/[slug].vue | 5 +++++ app/pages/p/[slug].vue | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) 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) }