[recovery] fix: setRequestLocale ordering in resources page (static→dynamic error)#18798
Merged
Merged
Conversation
✅ Deploy Preview for ethereumorg ready!
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
force-pushed
the
recovery/fix/resources-setrequestlocale-order
branch
from
July 15, 2026 16:34
2bd31c8 to
c23a377
Compare
pettinarip
marked this pull request as ready for review
July 15, 2026 16:39
Contributor
|
Merged
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Production error
grafana-fn-error-page-changed-from-static-to-dynamic-at-runtime-api-resources-reason-he/api/resourcesRoot cause
app/[locale]/resources/page.tsxcalledgetTranslations("page-resources")before ever callingsetRequestLocale(locale), andgenerateMetadatanever called it at all.The alerted URL
/api/resourcesis a bot/invalid path whereapiis captured as the[locale]segment. That isn't a valid locale, so it's not covered bygenerateStaticParamsand the route renders on-demand. next-intl then reads the locale from request headers, which opts the route into dynamic rendering, and Next.js throwsPage changed from static to dynamic at runtime.Fix
Call
setRequestLocale(locale)first — before any next-intl API — in bothPageandgenerateMetadata. 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