Repository navigation
perf(i18n): apply transparent rewrite, static pages, and zero-fouc theme - #279
Merged
Merged
Conversation
- Route directory restructured from src/app/ to src/app/[locale]/ with generateStaticParams() pre-rendering static HTML (SSG) for English and Arabic. - Middleware transparently rewrites unprefixed URLs (/, /leaderboard, etc.) directly to localized pages with zero URL redirect flicker. - Bypasses static assets, metadata files (manifest.webmanifest, robots, sitemap), and API routes from rewrite. - Retains inline blocking script in head for 0ms initial theme FOUC prevention and keeps client-side language switching reactive without router.refresh() to avoid theme flashing. - Adds darkreader-lock to suppress browser extension hydration mismatches and disables unused logo preload. - Adds comprehensive unit test suite in src/lib/i18n/tests/middleware.test.ts.
Owner
Author
|
✨ Thank you, @O2sa! Another great contribution merged! 🚀 You've been a fantastic contributor! We truly appreciate your continued support. |
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.
Summary
This PR migrates the application from dynamic server-side rendering (
ƒ Dynamic) to pre-rendered static generation (● SSG) for all core pages across both English and Arabic locales. It implements transparent Next.js middleware rewrites to maintain clean, prefix-free URLs (/,/leaderboard, etc.) without redirect hops, while resolving theme flashing (FOUC) on both initial page load and language toggle.Problem & Motivation
Pages previously relied on request-time
headers()andcookies()in the root layout, forcing Next.js to dynamically render every HTML request on demand (ƒ Dynamic), increasing TTFB and server compute.Standard Next.js internationalization typically forces route redirects (e.g.
//en), causing address-bar flickering and extra roundtrips.router.refresh()during language selection fetched a fresh Server Component Flight payload that wiped outclass="dark"fromdocument.documentElement, causing a white theme flash.BrandLogowas aggressively preloaded as an LCP candidate despite being a lightweight SVG, triggering browser preload warnings.<script>tags inside<head>.Key Changes & Architecture
1. Static Page Generation (
● SSG)src/app/[locale]/and exportedgenerateStaticParams():headers()andcookies()from layout trees, enabling Next.js Turbopack to pre-render static HTML for/enand/arat build time.revalidate = 3600,dynamicParams = true,generateStaticParams = () => []) for[country]leaderboard pages to eliminate cold-cache build timeouts.2. Transparent Middleware Rewrites
src/middleware.tsto detect the user's preferred language (app-localecookieAccept-Languageheader'en')./,/leaderboard,/scoring-methodology) with zero address-bar changes or redirect delays./api/*,manifest.webmanifest,robots.txt, andsitemap.xml.3. Zero-FOUC Theme & Flash-Free Language Switching
<head>that synchronizeslocalStorageandprefers-color-schemetodocument.documentElement.classListbefore browser paint (0ms FOUC).useI18nProvideris purely client-reactive (updates state dictionary, updatesdocument.documentElement.lang/dir, and writes the cookie). Removedrouter.refresh()fromLanguageSwitcherto prevent RSC DOM reconciliation from resettingclass="dark".theme-provider.tsxfor React 19's script tag advisory.4. Hydration & Performance Guardrails
"darkreader-lock": ""to metadata insrc/app/[locale]/layout.tsxto stop Dark Reader from mutating SVG icon DOM nodes before hydration.BrandLogopriority tofalseby default to eliminate browser preload warnings.typedRoutes: truefromnext.config.jsto ensure compatibility with transparent internal rewrites.Review Checklist
● SSG)/,/leaderboard, etc.) work seamlessly without redirects