Skip to content

[recovery] fix: setRequestLocale ordering in resources page (static→dynamic error)#18798

Merged
pettinarip merged 1 commit into
devfrom
recovery/fix/resources-setrequestlocale-order
Jul 16, 2026
Merged

[recovery] fix: setRequestLocale ordering in resources page (static→dynamic error)#18798
pettinarip merged 1 commit into
devfrom
recovery/fix/resources-setrequestlocale-order

Conversation

@pettinarip

Copy link
Copy Markdown
Member

Production error

[ERROR] Error: Page changed from static to dynamic at runtime /api/resources, reason: headers
    at get requestLocale (...)
  • Fingerprint: grafana-fn-error-page-changed-from-static-to-dynamic-at-runtime-api-resources-reason-he
  • URL: /api/resources
  • Hit count: 1 (first seen 2026-05-29)

Root cause

app/[locale]/resources/page.tsx called getTranslations("page-resources") before ever calling setRequestLocale(locale), and generateMetadata never called it at all.

The alerted URL /api/resources is a bot/invalid path where api is captured as the [locale] segment. That isn't a valid locale, so it's not covered by generateStaticParams and the route renders on-demand. next-intl then reads the locale from request headers, which opts the route into dynamic rendering, and Next.js throws Page changed from static to dynamic at runtime.

Fix

Call setRequestLocale(locale) first — before any next-intl API — in both Page and generateMetadata. This is the same fix class already applied to the wallets page (#18797) and videos [slug] page (#18785).

Verification

  • pnpm type-check
  • pnpm exec eslint app/[locale]/resources/page.tsx

🤖 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 c23a377
🔍 Latest deploy log https://app.netlify.com/projects/ethereumorg/deploys/6a57b6ac53f689000824bcb9
😎 Deploy Preview https://deploy-preview-18798.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: 60 (🟢 up 4 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.

…ynamic error)

The resources page called getTranslations("page-resources") before ever
calling setRequestLocale(locale), and generateMetadata never called it at
all. Bot/invalid paths like /api/resources are captured by the [locale]
catch-all with "api" as the locale segment. Since that isn't a valid
locale in generateStaticParams, the route renders on-demand and next-intl
reads the locale from request headers, opting the route into dynamic
rendering and throwing:

  Error: Page changed from static to dynamic at runtime /api/resources,
  reason: headers

Fix: call setRequestLocale(locale) first in both Page and generateMetadata,
before any next-intl API. Same fix class as the wallets/videos pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pettinarip
pettinarip force-pushed the recovery/fix/resources-setrequestlocale-order branch from 2bd31c8 to c23a377 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

Generated by PR Reviewer (team) for #18798 · 64.5 AIC · ⌖ 9.96 AIC · ⊞ 5.2K ·

@pettinarip
pettinarip merged commit e7fe982 into dev Jul 16, 2026
31 checks passed
@pettinarip
pettinarip deleted the recovery/fix/resources-setrequestlocale-order branch July 16, 2026 12:09
@claude claude Bot mentioned this pull request Jul 16, 2026
myelinated-wackerow added a commit that referenced this pull request Jul 16, 2026
Records the pattern behind recovery PRs #18785/#18797/#18798/#18800 and systemic fix #18811 so future work surfaces it before reintroducing the bug.

Every async Server Component page and generateMetadata under app/[locale]/ must call setRequestLocale(locale) before any next-intl API. next-intl's request config resolves the locale via requestLocale, which reads request headers unless setRequestLocale has primed the per-request cache; a next-intl call before priming opts the route into dynamic rendering and, for on-demand params (invalid-locale / unknown-slug bot probes not in generateStaticParams), throws "Page changed from static to dynamic at runtime, reason: headers". The getMetadata/getMdMetadata helpers call getTranslations("common") internally, so priming first is required even when locale is passed to them.

Canonical writeup: docs/solutions/architecture/setrequestlocale-static-to-dynamic-rendering.md (discoverable via the learnings-researcher agent). Thin pointers added in docs/best-practices.md (next-intl section) and the design-system skill (references/i18n-rtl.md + SKILL.md rule 5 and load trigger).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
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