Skip to content

fix(home): server-redirect / to /explore + unmask SSR errors#413

Merged
spe1020 merged 1 commit into
mainfrom
fix/homepage-ssr-500
Jun 2, 2026
Merged

fix(home): server-redirect / to /explore + unmask SSR errors#413
spe1020 merged 1 commit into
mainfrom
fix/homepage-ssr-500

Conversation

@spe1020
Copy link
Copy Markdown
Contributor

@spe1020 spe1020 commented Jun 2, 2026

What

Production returns HTTP 500 on the homepage (https://zap.cooking/). This fixes the symptom and ensures any future SSR failure is no longer masked.

Investigation (verified, not assumed)

  • Deploy target is Cloudflare Pages, not Vercel (deploy = wrangler pages deploy .svelte-kit/cloudflare; prod headers server: cloudflare). Repro was done on the real workerd runtime via wrangler pages dev.
  • Scope is isolated to /. Prod: / = 500, but /explore = 200, /recipes = 200, /membership = 200. /membership is also SSR'd through the Worker, so the Worker, hooks.server.ts, and the layout are all fine. The 500 shell shows node_ids:[0,1] with membershipEnabled resolved — i.e. the layout loaded and the / page node is what throws.
  • The real error is masked as the generic { message: "Internal Error" } because there was no handleError.

Changes

(b) src/routes/+page.server.ts (new)throw redirect(307, '/explore'). The homepage is just a doorway to /explore; redirecting in the server load short-circuits the response before any homepage page-component SSR render, so whatever was throwing in that render path is off the critical path. Also strictly better than SSR-rendering the whole app shell just to client-redirect in onMount.

+page.svelte — drops the invalid export const data: PageData = {} as PageData (page data must be a settable export let prop, not a read-only const — the one objectively-wrong line on the failing route). Keeps an onMount goto('/explore') fallback for in-app navigations to /.

(a) src/hooks.server.ts — adds handleError that logs the real error + stack (method, path, status, name, message, stack) while still returning a generic message to the client. Guarantees the next 500 is diagnosable.

Verification

  • pnpm check0 errors.
  • Cloudflare workerd repro (wrangler pages dev on the adapter-cloudflare build): /307 → /explore → 200; /explore 200; no throw in worker stderr.

Honest caveat

The prod 500 could not be reproduced locally — the exact deployed commit returns 200 on a faithful workerd build (with and without env vars), so the fault appears prod-environment/artifact specific and I could not capture the real stack (wrangler/Vercel auth unavailable). This is therefore a validated mitigation with ~80% confidence it resolves the symptom, not a confirmed-root-cause fix. Change (a) closes the gap: if anything still 500s after deploy, the stack will be in the function logs.

🤖 Generated with Claude Code

Production returns HTTP 500 on the homepage (Cloudflare Pages). Scope is
isolated to the `/` page node: /explore, /recipes, and /membership all 200,
and the 500 shell shows the layout loaded (node_ids:[0,1], membershipEnabled
resolved) — so the Worker, hooks, and layout are fine; only `/`'s page render
throws. The real stack is masked as the generic {message:"Internal Error"}.

Two changes:

(b) Add src/routes/+page.server.ts that throws redirect(307, '/explore'). The
    homepage is just a doorway to /explore; redirecting in the server load
    short-circuits the response BEFORE any homepage page-component SSR render,
    so whatever was throwing in that render path is no longer on the critical
    path. Strictly better than SSR-rendering the whole app shell only to
    client-redirect in onMount. Validated on the Cloudflare workerd runtime:
    / -> 307 -> /explore -> 200.

    +page.svelte: drop the invalid `export const data: PageData = {} as
    PageData` (page data must be a settable `export let` prop, not a read-only
    const — the one objectively-wrong line on the failing route). Keep an
    onMount goto('/explore') as a fallback for in-app navigations to `/`.

(a) Add handleError to hooks.server.ts so the real server-side error + stack
    is logged instead of silently masked. Without it, a render/load throw is
    invisible in the function logs beyond a bare 500. Client still receives a
    generic message; detail stays server-side. This guarantees the next 500
    (if any) is diagnosable.

Note: the prod 500 could not be reproduced locally — the exact deployed commit
returns 200 on a faithful workerd build (with and without env vars) — so this
is a validated mitigation, not a confirmed-root-cause fix. handleError closes
that gap going forward.

svelte-check: 0 errors. workerd repro: / 307->200, /explore 200.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
zapcooking-frontend dc0cd7f Jun 02 2026, 01:22 AM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
frontend dc0cd7f Jun 02 2026, 01:25 AM

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Mitigates a production-only SSR failure on the homepage (/) by redirecting requests to /explore before the route’s page component renders, and adds server-side error logging so future SSR failures surface actionable stack traces in function logs.

Changes:

  • Add a server load on / that throws a redirect to /explore, short-circuiting SSR for the problematic page node.
  • Remove an invalid export const data from the / page component and keep a client-side goto('/explore') fallback for SPA navigation edge-cases.
  • Add handleError in hooks.server.ts to log real SSR errors (method/path/status/message/stack) while returning a generic client error message.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/routes/+page.svelte Removes invalid page data export; keeps a client-side redirect fallback.
src/routes/+page.server.ts New server-side redirect from / to /explore to avoid SSR render on the failing node.
src/hooks.server.ts Adds handleError to log SSR errors with stack traces.
package.json Bumps application version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/routes/+page.svelte
Comment on lines +8 to 10
onMount(() => {
goto('/explore');
});
Comment on lines +11 to +13
export const load: PageServerLoad = () => {
throw redirect(307, '/explore');
};
Comment thread src/hooks.server.ts
Comment on lines +14 to +16
method: event.request.method,
path: event.url.pathname,
status,
@spe1020 spe1020 merged commit 5905c0d into main Jun 2, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants