Skip to main content
aapp-hacks
← Back to articles
Author
app-hacks
Published
Updated
Reviewed

JavaScript / i18n / UX

Implement a Browser-Language Notice Without Forced Redirects

Detect browser language, offer a non-modal language notice, and respect a visitor choice with localStorage.

Implement a Browser-Language Notice Without Forced Redirects

Browser language can help a multilingual site offer an alternative, but it should not override the URL someone deliberately opened. A bookmark, shared link, search result, or language-comparison task can matter more than a browser preference. Use that preference to show an option, not to force navigation.

Browser language can show an optional notice; the visitor chooses whether to follow the language link.

Why Avoid Forced Redirects

An automatic redirect can move an English-browser visitor away from a Japanese URL they chose, make language comparison difficult, and leave a shared URL different from the page being viewed. A non-modal notice and ordinary language link communicate that an alternative exists while keeping control with the visitor.

Detect Only Supported Languages

Browsers can return an ordered language list. Check it in order and accept only languages the site supports.

type SupportedLanguage = 'ja' | 'en';

function getPreferredSupportedLanguage(): SupportedLanguage | null {
  const candidates = navigator.languages?.length
    ? navigator.languages
    : [navigator.language];

  for (const candidate of candidates) {
    const language = candidate.toLowerCase().split('-')[0];
    if (language === 'ja' || language === 'en') return language;
  }

  return null;
}

This handles regional values such as en-US by checking the part before -. Treat unsupported languages as null rather than guessing a destination.

Separate Notice Logic from Navigation

On a Japanese page, an English preference can make an English link eligible for display only when that version exists.

const preferred = getPreferredSupportedLanguage();
const shouldOfferEnglish =
  currentLanguage === 'ja' && preferred === 'en' && hasEnglishVersion;

This is display logic only. Do not call location.href or location.replace(). Navigate normally only after the visitor chooses the link, preserving browser history and the meaning of the original URL.

Store a Safe Display Choice

To avoid repeating a notice, a site can store a minimal language choice. Guard storage access because browser privacy settings can block it.

function readLanguageChoice(): SupportedLanguage | null {
  try {
    const value = localStorage.getItem('app-hacks.language');
    return value === 'ja' || value === 'en' ? value : null;
  } catch {
    return null;
  }
}

This is a display preference, not a place for credentials, email addresses, or behavioral history. The page should remain readable and ordinary language links should still work when storage is unavailable.

Verify Both Versions

Check that each language link points to a page that exists, that a saved choice suppresses unnecessary notices, and that pages without a translation do not show a false option. Browser language is supplementary information; leaving URL choice with the visitor makes the experience predictable.