Skip to content

[recovery] fix: setRequestLocale ordering in [...slug] generateMetadata (static→dynamic error)#18800

Open
pettinarip wants to merge 1 commit into
devfrom
recovery/fix/slug-catchall-setrequestlocale-order
Open

[recovery] fix: setRequestLocale ordering in [...slug] generateMetadata (static→dynamic error)#18800
pettinarip wants to merge 1 commit into
devfrom
recovery/fix/slug-catchall-setrequestlocale-order

Conversation

@pettinarip

Copy link
Copy Markdown
Member

Production error

  • Fingerprint: grafana-fn-error-page-changed-from-static-to-dynamic-at-runtime-images-videos-clw-qfnsu
  • Message: [ERROR] ⨯ Error: Page changed from static to dynamic at runtime /images/videos/Clw-qf1sUZg.jpg, reason: headers
  • Hit count: 2
  • Stack terminates in get requestLocale (next-intl).

Root cause

/images/videos/Clw-qf1sUZg.jpg has no static asset and falls through to the catch-all app/[locale]/[...slug]/page.tsx with locale="images", slug=["videos","Clw-qf1sUZg.jpg"] (a bot/broken-link probe against a YouTube-ID-shaped path).

generateMetadata in that route never called setRequestLocale(locale) before invoking next-intl APIs:

  • the happy path getMdMetadatagetMetadata calls getTranslations("common") (src/lib/utils/metadata.ts:66);
  • the catch block also calls getTranslations("common").

Without setRequestLocale, next-intl falls back to reading the locale from request headers() for on-demand slugs (those not covered by generateStaticParams), which opts the route into dynamic rendering and throws "Page changed from static to dynamic at runtime … reason: headers".

Fix

Add setRequestLocale(locale) at the top of generateMetadata, before any next-intl call. Same class of fix as #18785 (videos slug), #18797 (wallets), #18798 (resources).

Verification

  • pnpm type-check
  • pnpm exec eslint on changed file ✅

🤖 Generated with Claude Code

@pettinarip pettinarip added the recovery-agent Created by the Recovery Agent label Jul 14, 2026
@netlify

netlify Bot commented Jul 14, 2026

Copy link
Copy Markdown

Deploy Preview for ethereumorg ready!

Name Link
🔨 Latest commit dc9c0cd
🔍 Latest deploy log https://app.netlify.com/projects/ethereumorg/deploys/6a57b6af369e0e0008c2e4f9
😎 Deploy Preview https://deploy-preview-18800.ethereum.it
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
7 paths audited
Performance: 58 (🟢 up 2 from production)
Accessibility: 95 (no change from production)
Best Practices: 100 (no change from production)
SEO: 98 (no change from production)
PWA: 59 (🔴 down 1 from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

The catch-all [locale]/[...slug] generateMetadata never called
setRequestLocale before invoking next-intl APIs. getMdMetadata ->
getMetadata calls getTranslations("common"), and the catch block also
calls getTranslations("common"). Without setRequestLocale, next-intl
reads the locale from request headers for on-demand slugs, opting the
route into dynamic rendering and throwing "Page changed from static to
dynamic at runtime ... reason: headers".

Observed in production via /images/videos/Clw-qf1sUZg.jpg, which maps to
the catch-all with locale="images".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pettinarip pettinarip force-pushed the recovery/fix/slug-catchall-setrequestlocale-order branch from 6478b4a to dc9c0cd Compare July 15, 2026 16:34
@pettinarip pettinarip marked this pull request as ready for review July 15, 2026 16:39
@pettinarip pettinarip requested a review from wackerow as a code owner July 15, 2026 16:39
@github-actions

Copy link
Copy Markdown
Contributor

🔎 First-pass review — ✅ Looks mergeable

Single-line fix adding setRequestLocale(locale) at the top of generateMetadata in the [...slug] catch-all, before any next-intl call. This is the correct fix for the "Page changed from static to dynamic at runtime ... reason: headers" error: without it, on-demand slugs (not covered by generateStaticParams) make next-intl fall back to reading the locale from headers(), opting the route into dynamic rendering. Both the happy path (getMdMetadatagetTranslations) and the catch block (getTranslations("common")) are now covered.

Analysis

Generated by PR Reviewer (team) for #18800 · 67.3 AIC · ⌖ 24 AIC · ⊞ 5.2K ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review 👀 recovery-agent Created by the Recovery Agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant