Skip to content

feat(i18n): detect browser language, drive locales from one table - #5

Merged
DennisBauer merged 1 commit into
mainfrom
feat/browser-language-detection
Aug 11, 2026
Merged

feat(i18n): detect browser language, drive locales from one table#5
DennisBauer merged 1 commit into
mainfrom
feat/browser-language-detection

Conversation

@DennisBauer

@DennisBauer DennisBauer commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

GitHub Pages serves static files, so there is no Accept-Language to branch on: an inline pre-paint script in Base.astro redirects instead. Only the unprefixed URLs redirect — a prefixed one is an explicit choice, which keeps shared links in their language and makes a loop impossible. Using the header switch records the choice in localStorage, where it outranks detection from then on; without that the redirect would trap anyone whose browser language isn't the one they want.

The same change generalises the locale handling, because a third language would otherwise have rendered while being invisible to detection, the switch, og:locale, date formatting and the Play badge. src/i18n/locales.ts is now the only place a language is declared, and astro.config.ts derives its routes and sitemap from it rather than repeating the list. The switch turns into a dropdown from three languages on; LOCALIZED_SLUGS became Partial so that translated slugs stay opt-in instead of a type error.

Both privacy pages now name the second localStorage key, since they claimed the theme preference was the only thing this site stores.

Summary by CodeRabbit

  • New Features

    • Improved language switching with accessible menus, translated labels, locale-aware links, and keyboard/outside-click controls.
    • Added automatic browser-language redirection for eligible default-language pages.
    • Added localized store badges with an English fallback.
    • Added support for localized slugs and expanded multilingual page routing.
    • Improved localized page metadata and language references for search and sharing.
  • Documentation

    • Added guidance for registering languages, translations, localized pages, slugs, badges, redirects, and language dropdown behavior.
  • Bug Fixes

    • Corrected German language-switch text and updated privacy policies to document locally stored language preferences.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 12700bdf-8f72-46be-a9d7-20dfd315b4cb

📥 Commits

Reviewing files that changed from the base of the PR and between e0d3c8c and 98f9273.

📒 Files selected for processing (1)
  • src/layouts/Base.astro
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/layouts/Base.astro

Walkthrough

The PR centralizes locale metadata and utilities. It adds multi-locale switching, browser-language redirects, localized badges, metadata-driven configuration, and documentation for adding languages and storing language preferences locally.

Changes

Locale support

Layer / File(s) Summary
Centralized locale contracts and URL utilities
src/i18n/locales.ts, src/i18n/utils.ts
Supported locales, metadata, validation, alternate-locale enumeration, optional localized slugs, and redirect target generation are centralized.
Locale configuration and page metadata
astro.config.ts, src/layouts/Base.astro, src/layouts/Legal.astro
Astro, sitemap, HTML, Open Graph, redirect, and date-formatting values now use locale metadata.
Multi-locale language selection
src/components/LangSwitch.astro, src/components/ui/StoreBadges.astro, src/i18n/en.ts, src/i18n/de.ts
The language switcher supports direct links and multi-option menus. Locale selection is stored locally, and Play Store badges use locale mappings with English fallback.
Browser-language redirect flow
src/layouts/Base.astro
Eligible default-locale pages match stored or browser languages and preserve query strings and hashes during redirects.
Locale onboarding and storage disclosure
README.md, src/pages/privacy.mdx, src/pages/de/privacy.mdx
Documentation covers language setup. Privacy policies describe local language preference storage and use updated dates.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant BaseLayout
  participant RedirectTargets
  participant LocalizedPage
  Browser->>BaseLayout: Load default-locale page
  BaseLayout->>RedirectTargets: Read locale redirect candidates
  RedirectTargets-->>BaseLayout: Return localized URLs
  BaseLayout->>Browser: Match stored or browser language
  Browser->>LocalizedPage: Navigate with query and hash preserved
Loading

Possibly related PRs

  • TabMates/website#4: Updates related localized translation content in src/i18n/en.ts and src/i18n/de.ts.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: browser-language detection and centralized locale configuration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/LangSwitch.astro (1)

93-126: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove is:inline from the LangSwitch script.

This script does not run before paint or require verbatim output. Use a processed <script> to enable Astro’s TypeScript diagnostics and script deduplication. Type the queried elements and event values as needed.

🤖 Prompt for 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.

In `@src/components/LangSwitch.astro` around lines 93 - 126, Remove is:inline from
the LangSwitch script so Astro processes it, then add the necessary TypeScript
annotations for queried menu/link elements and event targets or values while
preserving the existing behavior. Keep the click, storage, menu-closing, and
Escape-key handling unchanged, relying on Astro’s processed-script
deduplication.
🤖 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 `@src/layouts/Base.astro`:
- Around line 60-68: Update the langRedirect condition in Base.astro to require
noLangSwitch to be disabled before creating browser redirect targets. Preserve
the existing DEFAULT_LOCALE and noindex checks, and ensure pages marked
noLangSwitch produce no redirect configuration.

---

Nitpick comments:
In `@src/components/LangSwitch.astro`:
- Around line 93-126: Remove is:inline from the LangSwitch script so Astro
processes it, then add the necessary TypeScript annotations for queried
menu/link elements and event targets or values while preserving the existing
behavior. Keep the click, storage, menu-closing, and Escape-key handling
unchanged, relying on Astro’s processed-script deduplication.
🪄 Autofix

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 Plus

Run ID: 789bc8f6-b662-45cd-9374-ea30b1b5873a

📥 Commits

Reviewing files that changed from the base of the PR and between 1f80183 and e0d3c8c.

📒 Files selected for processing (12)
  • README.md
  • astro.config.ts
  • src/components/LangSwitch.astro
  • src/components/ui/StoreBadges.astro
  • src/i18n/de.ts
  • src/i18n/en.ts
  • src/i18n/locales.ts
  • src/i18n/utils.ts
  • src/layouts/Base.astro
  • src/layouts/Legal.astro
  • src/pages/de/privacy.mdx
  • src/pages/privacy.mdx

Comment thread src/layouts/Base.astro
GitHub Pages serves static files, so there is no Accept-Language to branch
on: an inline pre-paint script in Base.astro redirects instead. Only the
unprefixed URLs redirect — a prefixed one is an explicit choice, which keeps
shared links in their language and makes a loop impossible. Using the header
switch records the choice in localStorage, where it outranks detection from
then on; without that the redirect would trap anyone whose browser language
isn't the one they want.

The same change generalises the locale handling, because a third language
would otherwise have rendered while being invisible to detection, the switch,
og:locale, date formatting and the Play badge. src/i18n/locales.ts is now the
only place a language is declared, and astro.config.ts derives its routes and
sitemap from it rather than repeating the list. The switch turns into a
dropdown from three languages on; LOCALIZED_SLUGS became Partial so that
translated slugs stay opt-in instead of a type error.

Both privacy pages now name the second localStorage key, since they claimed
the theme preference was the only thing this site stores.
@DennisBauer
DennisBauer force-pushed the feat/browser-language-detection branch from e0d3c8c to 98f9273 Compare August 11, 2026 14:02
@DennisBauer
DennisBauer merged commit 05eaa88 into main Aug 11, 2026
2 checks passed
@DennisBauer
DennisBauer deleted the feat/browser-language-detection branch August 11, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant