Features / Language Switcher

Language Switcher

polyglot add switcher scaffolds a language switcher directly into your repo — code you own and restyle, not a runtime dependency you import.

Once your app is translated, users need a way to change languages. Rather than ship a black-box component that fights your design system, Polyglot generates the switcher as source files in your project. You own them, version them, and style them like any other component.

Usage

polyglot add switcher

Polyglot detects your framework (from polyglot.toml, or by inspecting the project) and writes the switcher into your components directory.

Options

  • --framework <name> — override detection. The switcher scaffolds an adapter for every supported framework, e.g. nextjs (next-intl), plus SvelteKit, Vue, Astro, Angular, React Native, and Flutter.
  • --dir <path> — target directory (defaults to src/components or components).
  • --force — overwrite files that already exist.

What it generates

For a Next.js project, two files land in your components directory:

src/components/
  language-switcher.tsx   # framework-agnostic UI shell
  locale-switcher.tsx     # next-intl adapter

language-switcher.tsx — the shell

A pure presentational component with zero dependencies beyond React. It takes the list of locales, the current locale, and an onSelect callback, and renders the dropdown. Language names come from the platform's Intl.DisplayNames, so each renders in its own script (Deutsch, 日本語, العربية) with no data to maintain, and right-to-left locales are handled automatically.

locale-switcher.tsx — the adapter

The thin, framework-specific piece. It reads the active locale and performs the route-based switch — the only part that knows about your router. Swapping frameworks means swapping this file; the shell stays identical.

Wiring it up

Render the adapter in your header or nav:

import LocaleSwitcher from "@/components/locale-switcher";

export default function Header() {
  return (
    <nav>
      {/* ...your links... */}
      <LocaleSwitcher tone="dark" />
    </nav>
  );
}

Then open locale-switcher.tsx and set the two constants to match your i18n configuration:

const LOCALES = ["en", "de", "fr"];
const DEFAULT_LOCALE = "en";

Requirements & assumptions

  • The Next.js adapter assumes next-intl with localePrefix: "as-needed" (the default locale is unprefixed). For always prefixing, remove the DEFAULT_LOCALE special-case in the adapter.
  • tone accepts "dark" or "light" to match the surrounding chrome. Everything else is plain Tailwind classes you can edit.

Why owned code, not a package

A language switcher is highly app-specific — placement, styling, and routing all differ between projects. Shipping it as an imported component would couple you to our versioning and fight your design system. Scaffolding it as source means you get a working starting point and full control, in keeping with Polyglot's approach: you own your i18n, with no lock-in.

Language Switcher - Docs | Polyglot