Hardening: fetch races, i18n locale authority, server-side lang, lint#9
Merged
Hardening: fetch races, i18n locale authority, server-side lang, lint#9
Conversation
…utes, restore lint - Cap route geometry to 2000 coordinates and LIMIT SQL results to 500 (route-stations) - Downsample Valhalla polylines to 2000 points before sending to corridor API - Make URL [locale] param authoritative for i18n instead of localStorage/browser - Sync <html lang> with active locale, navigate on locale switch - Add AbortController to route requests to prevent stale-response races - Fix lint: drop FlatCompat, use eslint-config-next flat config, pin ESLint 9 - Re-enable lint step in CI workflow
…lint, bbox - Middleware reads pumperly-locale cookie before Accept-Language, preventing default-locale bounce-back for users who explicitly chose a language - setLocale persists choice in cookie alongside localStorage - Navbar logo links to current locale path instead of hardcoded / - handleClearRoute aborts in-flight route requests via routeAbortRef - Route-stations SQL uses CTE + ROW_NUMBER uniform sampling instead of naive LIMIT 500, distributing stations evenly along the entire route - Compute bbox from full-resolution coords before downsampling in valhalla.ts - Fix react-hooks/exhaustive-deps in station-layer.tsx (setSelectedStationId) - Ignore src/generated/ in eslint config; lint now passes with 0 errors
…y copy
- Fix stale corridor-fetch race: debounce effect now depends on routes
and reads fuel/routes from refs so timer always uses current values
- Logo always links to /${locale} (including es) — no cookie dependency
for fresh visitors who land on /es
- setLocale navigates to /${locale} consistently (no special-case for es)
- Set pumperly-locale cookie on initial render so middleware has it
even before the user explicitly switches language
- Locale layout sets document.documentElement.lang via inline script
before hydration — crawlers and a11y tools see it in initial HTML
- Update privacy policy: document the single functional locale cookie
…server-side html lang - Corridor debounce effect now only triggers on corridorKm changes (not route changes), preventing duplicate station fetches on every route activation - All locales including default (es) use /locale prefix in canonical URLs and hreflang, matching the navigation behavior - Middleware passes detected locale via x-pumperly-locale request header + sets cookie; root layout reads header to render lang attribute in server HTML - Remove redundant inline script from locale layout (no longer needed)
A pending bbox debounce timer could abort an in-flight corridor fetch when routes activated within ~100ms of a map pan, leaving the station list empty. Fix: - Split shared abortRef into bboxAbortRef and corridorAbortRef so neither fetch path can cancel the other - Clear bbox debounce timer on route activation - Guard fetchStations() with routesRef check to bail if routes are active
Without this, a slow route-stations response could repopulate corridorPerRoute after the route was cleared, leaking stale stations into the next route activation.
GeiserX
added a commit
that referenced
this pull request
Apr 3, 2026
Hardening: fetch races, i18n locale authority, server-side lang, lint
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
Multi-round hardening pass covering fetch race conditions, i18n consistency, and tooling.
Fetch safety (map-view)
abortRefinto independentbboxAbortRef/corridorAbortRef— bbox and corridor fetches can no longer cancel each otherfetchStations()against route modecorridorKmchangeshandleClearRouteRoute-stations endpoint
LIMIT 500with CTE + ROW_NUMBER uniform spatial samplingi18n / locale
setLocale()writes cookie + navigates to/{locale}x-pumperly-localerequest header → root layout renders<html lang>server-sidees) use/localeprefix in canonical URLs and hreflang/{locale}(no bounce-back for fresh visitors)pumperly-localecookieLint / tooling
react-hooks/exhaustive-depsin station-layerTest plan
npm run buildpassesnpm run lintpasses (0 errors, 2 pre-existing scraper warnings)lang/fr—<html lang="fr">in server response