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
- Locale Inspector — parse any BCP 47 tag
- Variant Builder — construct a locale from parts
- Round-trip Tester — verify variant round-tripping
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗