fix: preload English translations to eliminate i18n skeleton loaders#29428
fix: preload English translations to eliminate i18n skeleton loaders#29428mdayan8 wants to merge 2 commits into
Conversation
Preload en/common.json at module level so translation data is available on the first render in the Pages Router. Also cache tRPC i18n results per locale for instant back-navigation. Previously the CustomI18nextProvider waited for a tRPC query before providing any translation resources, causing isLocaleReady to be false and every component to render skeleton loaders. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Welcome to Cal.diy, @mdayan8! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR preloads English i18n from common.json at module load, adds an in-memory per-locale i18nCache, and updates CustomI18nextProvider to store fetched clientViewerI18n into the cache. i18n selection now prefers fresh clientViewerI18n, then props.pageProps.i18n, then i18nCache[locale], and finally the englishFallback. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/lib/app-providers.tsx`:
- Around line 129-131: The render currently mutates module-level i18nCache
(calling i18nCache.set(locale, clientViewerI18n.data.i18n)) inside the component
render; move that write into a useEffect so CustomI18nextProvider (or the
component exporting clientViewerI18n/locale) remains pure—add a useEffect that
depends on locale and clientViewerI18n.data?.i18n and perform i18nCache.set(...)
inside it, and remove the i18nCache.set call from the render path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d35bec02-487b-4848-afb3-12d701ccf47d
📒 Files selected for processing (1)
apps/web/lib/app-providers.tsx
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@AminDhouib Thanks for the clarification. I appreciate the response and understand the project's contribution workflow. Thanks for taking the time to review it. Wishing the team continued success with the project! |
Problem
The Pages Router shows skeleton loaders on every navigation while waiting for a tRPC query to fetch translation strings. This creates a jarring flicker where the entire UI flashes skeleton placeholders before content appears — especially noticeable on initial load and locale switches.
The
CustomI18nextProviderfires a tRPCviewer.i18n.getquery, and while it's pending,pageProps.i18nisundefined. SinceappWithTranslationhas no resources,isLocaleReadyisfalse, and every component checking it renders skeleton loaders.Solution
English fallback preload: Load
en/common.jsonat module level (it's a static JSON asset already bundled by webpack) and format it as anSSRConfigfallback. This means translation data is available on the very first render — no skeleton needed.Per-locale cache: Cache tRPC i18n results in a
Map<string, SSRConfig>keyed by locale. Switching back to a previously-visited locale is instant, no network request wait.Together these ensure
isLocaleReadyis alwaystruefrom the first render.How it works
The priority chain is:
tRPC data -> pageProps.i18n -> locale cache -> English fallback
When the tRPC query resolves, its locale-specific data replaces the English fallback seamlessly. This mirrors what
mergeWithEnglishFallbackalready does on the server.Related
Relevant to the issue described in #9840 and RFC #10198. App Router already handles this correctly (preloads in layout.tsx). This brings the same guarantee to the Pages Router.