v149 · Intl.Locale · negotiation

Language Negotiation

Given a user's language preferences (accept-languages) and a site's available locales, find the best match — taking variant subtags into account. Intl.Locale.prototype.variants makes variant-aware negotiation possible without string parsing.

Quick scenario presets:

User's preferred languages (accept-language order)
Site's available locales
Results
Click Negotiate to see the best match.
// Use locale.variants for variant-aware negotiation
function negotiateBestMatch(preferred, available) {
  const locales = available.map(t => new Intl.Locale(t));

  for (const pref of preferred) {
    const prefLocale = new Intl.Locale(pref);
    // Exact match: language + script + region + variants
    const exact = locales.find(l =>
      l.language === prefLocale.language &&
      l.script   === prefLocale.script   &&
      l.region   === prefLocale.region   &&
      arraysEqual(l.variants, prefLocale.variants)
    );
    if (exact) return { locale: exact, score: 'exact' };

    // Variant-partial: same language/script/region, variants subset
    const partial = locales.find(l =>
      l.language === prefLocale.language &&
      prefLocale.variants.every(v => l.variants.includes(v))
    );
    if (partial) return { locale: partial, score: 'partial-variant' };

    // Language-only fallback
    const langOnly = locales.find(l => l.language === prefLocale.language);
    if (langOnly) return { locale: langOnly, score: 'language-fallback' };
  }
  return { locale: new Intl.Locale(available[0]), score: 'no-match' };
}

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗