Skip to content

fix: remove OG-only server loads to stop profile/recipe 500s#454

Merged
spe1020 merged 2 commits into
mainfrom
fix/profile-500-remove-og-server-loads
Jun 19, 2026
Merged

fix: remove OG-only server loads to stop profile/recipe 500s#454
spe1020 merged 2 commits into
mainfrom
fix/profile-500-remove-og-server-loads

Conversation

@spe1020

@spe1020 spe1020 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Production CF Pages is serving a stale/dead worker because the worker build OOMs. __data.json requests that escape the service worker fall through to the dead worker and 500 — crashing on server loads whose only purpose was building Open Graph meta tags.

This PR fixes it at the source:

  • Remove OG-only +page.server.ts from user/[slug], recipe/[slug], r/[naddr], reads/[naddr], premium/recipe/[slug], market/kitchen/[npub], and [nip19]. These page nodes are now load-less, so SvelteKit no longer requests server __data.json for them — which removes the SW-race 500 class entirely.
  • OG/title/description/image moved into <svelte:head>, derived client-side from data already fetched over NDK.
  • [nip19] NIP-05 username redirect preserved: the bare-username → /user/<npub> redirect (previously done by the server load) is reimplemented client-side via /.well-known/nostr.json.
  • Raise build Node heap (NODE_OPTIONS=--max-old-space-size=6144) so the Cloudflare worker bundle stops OOMing during the build. (/api/* routes are still served by the worker, so adapter-static is not an option — the OOM had to be fixed.)

Net: −2,044 / +136 lines, 7 server loads deleted.

Verification (local wrangler pages dev / workerd, same runtime as prod)

  • Affected routes issue no __data.json request.
  • /api/counts/[eventId] and /api/counts/batch return real, non-zero counts (outbound new WebSocket works in the pinned workerd; calls are try/catch-guarded so worst case is silent-degrade, never 500).
  • [nip19] headless-browser checks:
    • bare username /seth → client-redirects to /user/<npub>
    • note1 / nevent1 → render the note view ✓
    • npub1 / naddr1 → "Note not found" (parity with prior behavior)
    • garbage → soft 404, no loop/hang/500 ✓

Test plan

  • Deploy a fresh worker (confirms OOM build fix).
  • Incognito (SW not yet controlling): click profiles/recipes repeatedly — no 500s.
  • Verify OG previews still render for shared profile/recipe/note links.
  • Confirm /<username> still redirects to the profile.

Notes / follow-ups (out of scope)

  • Garbage paths return a soft 404 (HTTP 200 + "Note not found" UI), unchanged from before.
  • npub1/naddr1 at the [nip19] catch-all show "Note not found" rather than redirecting; optional future enhancement to redirect them to /user and /r respectively.

Made with Cursor

The CF Pages worker build OOMs, leaving a stale/dead worker in
production. __data.json requests that escape the service worker fall
through to that worker and 500 on server loads whose only job was to
build Open Graph meta tags.

Remove the OG-only +page.server.ts from user/[slug], recipe/[slug],
r/[naddr], reads/[naddr], premium/recipe/[slug], market/kitchen/[npub]
and [nip19], so these load-less page nodes no longer request server
__data.json. OG/title/description/image are now derived client-side in
<svelte:head> from data already fetched over NDK. The [nip19] route
keeps its NIP-05 username -> /user/<npub> redirect, reimplemented
client-side via /.well-known/nostr.json.

Also raise the build Node heap (NODE_OPTIONS=--max-old-space-size=6144)
so the cloudflare worker bundle stops OOMing during CI.

Verified against `wrangler pages dev` (workerd): the affected routes
issue no __data.json, the /api/counts/* endpoints return real counts,
and the [nip19] redirect/render/404 paths behave with no loops or 500s.

Co-authored-by: Cursor <[email protected]>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 19, 2026

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 1268389 Jun 19 2026, 12:21 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 19, 2026

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 1268389 Jun 19 2026, 12:23 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploying frontend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1268389
Status: ✅  Deploy successful!
Preview URL: https://a22704bb.frontend-hvd.pages.dev
Branch Preview URL: https://fix-profile-500-remove-og-se.frontend-hvd.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to prevent production 500s caused by SvelteKit __data.json requests hitting a stale/dead Cloudflare Pages worker by removing OG-only server load functions on several routes and shifting OG meta generation into client-derived <svelte:head> data. It also increases the Node heap size for builds to avoid OOM during the worker bundle build step.

Changes:

  • Removed multiple route-level +page.server.ts files that were only used for OG metadata/redirect behavior, reducing server __data.json fetches.
  • Reworked several pages to derive OG/title/description/image from client-fetched NDK data and set tags via <svelte:head>.
  • Updated build scripts to run Vite with a larger Node old-space heap (--max-old-space-size=6144).

Reviewed changes

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

Show a summary per file
File Description
src/routes/user/[slug]/+page.svelte Removes dependency on server-provided ogMeta; uses client-derived defaults/NDK profile data for head meta.
src/routes/user/[slug]/+page.server.ts Deleted OG-only server load (and relay WebSocket OG fetch logic).
src/routes/recipe/[slug]/+page.svelte Removes server ogMeta usage and computes head meta from client-fetched recipe event.
src/routes/recipe/[slug]/+page.server.ts Deleted OG/redirect server load (tracking-param redirects + relay OG fetch).
src/routes/reads/[naddr]/+page.svelte Removes server ogMeta usage and computes article head meta from client-fetched event.
src/routes/reads/[naddr]/+page.server.ts Deleted OG/redirect server load (tracking-param redirects + relay OG fetch).
src/routes/r/[naddr]/+page.svelte Removes server ogMeta usage and computes recipe head meta from client-fetched event.
src/routes/r/[naddr]/+page.server.ts Deleted OG/redirect server load (tracking-param redirects + relay OG fetch).
src/routes/premium/recipe/[slug]/+page.server.ts Deleted premium recipe OG/redirect server load.
src/routes/market/kitchen/[npub]/+page.svelte Replaces server ogMeta with kitchen-derived client values in <svelte:head>.
src/routes/market/kitchen/[npub]/+page.server.ts Deleted kitchen OG server load (relay WebSocket OG fetch logic).
src/routes/[nip19]/+page.svelte Removes server ogMeta usage, adds client-side OG meta derivation + username resolution via /.well-known/nostr.json.
src/routes/[nip19]/+page.server.ts Deleted OG/redirect server load (tracking-param redirects + relay OG fetch).
package.json Increases Node heap for build scripts to reduce OOM risk on worker bundle build.
Comments suppressed due to low confidence (3)

src/routes/recipe/[slug]/+page.svelte:21

  • The deleted +page.server.ts used to 301-redirect away common tracking params (utm_*, fbclid, etc.). With it removed, these URLs will now persist and be shared/bookmarked, which can lead to duplicate-canonical URLs and cache fragmentation. Consider stripping them client-side for parity (using goto(..., { replaceState: true })).
<script lang="ts">
  import { browser } from '$app/environment';
  import { page } from '$app/stores';
  import { ndk } from '$lib/nostr';
  import type { NDKEvent } from '@nostr-dev-kit/ndk';
  import { nip19 } from 'nostr-tools';
  import { goto } from '$app/navigation';
  import Recipe from '../../../components/Recipe/Recipe.svelte';
  import PanLoader from '../../../components/PanLoader.svelte';
  import { GATED_RECIPE_KIND } from '$lib/consts';

  let event: NDKEvent | null = null;
  let naddr: string = '';
  let loading = true;
  let error: string | null = null;

  $: {
    if (browser && $page.params.slug) {
      loadData();
    }
  }

src/routes/r/[naddr]/+page.svelte:21

  • The removed +page.server.ts used to strip tracking params via a 301 redirect. Without a replacement, /r/<naddr>?utm_… will now remain as-is, increasing duplicate URLs and reducing cache hit rates. Consider stripping tracking params on the client for parity and canonicalization.
<script lang="ts">
  import { browser } from '$app/environment';
  import { page } from '$app/stores';
  import { ndk } from '$lib/nostr';
  import type { NDKEvent } from '@nostr-dev-kit/ndk';
  import { nip19 } from 'nostr-tools';
  import Recipe from '../../../components/Recipe/Recipe.svelte';
  import PanLoader from '../../../components/PanLoader.svelte';
  import { GATED_RECIPE_KIND, RECIPE_TAGS } from '$lib/consts';
  import ArrowLeftIcon from 'phosphor-svelte/lib/ArrowLeft';

  let event: NDKEvent | null = null;
  let naddr: string = '';
  let loading = true;
  let error: string | null = null;

  $: {
    if (browser && $page.params.naddr) {
      loadData();
    }
  }

src/routes/reads/[naddr]/+page.svelte:22

  • The deleted +page.server.ts stripped common tracking params via redirect. Without a client-side equivalent, /reads/<naddr>?utm_… will persist and can cause duplicate-canonical URLs and cache fragmentation. Consider stripping them client-side before loading the article.
<script lang="ts">
  import { browser } from '$app/environment';
  import { page } from '$app/stores';
  import { ndk } from '$lib/nostr';
  import type { NDKEvent } from '@nostr-dev-kit/ndk';
  import { nip19 } from 'nostr-tools';
  import Recipe from '../../../components/Recipe/Recipe.svelte';
  import PanLoader from '../../../components/PanLoader.svelte';
  import { RECIPE_TAGS } from '$lib/consts';
  import { validateMarkdownTemplate } from '$lib/parser';
  import ArrowLeftIcon from 'phosphor-svelte/lib/ArrowLeft';

  let event: NDKEvent | null = null;
  let naddr: string = '';
  let loading = true;
  let error: string | null = null;

  $: {
    if (browser && $page.params.naddr) {
      loadData();
    }
  }

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

}

// Resolve the author's display name for the OG title once the note loads.
$: if (event?.author) {
Comment on lines 12 to 16
import NoteActionBar from '../../components/NoteActionBar.svelte';
import ClientAttribution from '../../components/ClientAttribution.svelte';
import type { NDKEvent } from '@nostr-dev-kit/ndk';
import type { PageData } from './$types';
import { createCommentFilter } from '$lib/commentFilters';
import PostActionsMenu from '../../components/PostActionsMenu.svelte';
Comment on lines +197 to +205
// Plain zap.cooking NIP-05 username (not a NIP-19 identifier): resolve to
// a pubkey via /.well-known/nostr.json and redirect to the profile page.
// This mirrors the behavior the deleted +page.server.ts used to provide.
const isNip19 = /^(?:npub1|nprofile1|note1|nevent1|naddr1)/.test(nip19Id);
if (!isNip19 && /^[a-zA-Z0-9_]{3,20}$/.test(nip19Id)) {
const username = nip19Id.toLowerCase();
try {
const res = await fetch('/.well-known/nostr.json?name=' + encodeURIComponent(username));
if (res.ok) {
The deleted OG-only +page.server.ts loads used to 301-redirect away
tracking params (utm_*, fbclid, gclid, ref, source, ...) for URL
canonicalization. Restore that behavior client-side via a shared
stripTrackingParams() helper that removes them and replaceState()s to
the clean URL, on the five routes that previously did this: recipe/[slug],
r/[naddr], reads/[naddr], premium/recipe/[slug], and [nip19].

Addresses Copilot review feedback on PR #454.

Co-authored-by: Cursor <[email protected]>
@spe1020 spe1020 merged commit e3e7973 into main Jun 19, 2026
5 of 7 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