@shelchin/svelte-i18n
Version:
The last Svelte i18n library you'll ever need. Type-safe, AI-powered, zero-config.
57 lines (56 loc) • 1.91 kB
JavaScript
/**
* Browser detection utilities
* Centralizes all browser language detection logic
*/
/**
* Detect the browser's preferred language
* @returns The detected language code or null if not available
*/
export function detectBrowserLanguage() {
if (typeof window === 'undefined' || !window.navigator) {
return null;
}
const nav = window.navigator;
// Check navigator.languages first (preferred)
if (nav.languages && nav.languages.length > 0) {
return nav.languages[0];
}
const browserLang = nav.language || nav.userLanguage || nav.browserLanguage || nav.systemLanguage;
return browserLang || null;
}
/**
* Get the browser's preferred language, matching against available locales
* @param availableLocales - List of supported locales
* @returns The matched locale or null if no match found
*/
export function getBrowserLocale(availableLocales) {
const browserLang = detectBrowserLanguage();
if (!browserLang) {
return null;
}
// If no available locales specified, return the browser language as-is
if (!availableLocales || availableLocales.length === 0) {
return browserLang;
}
// Try exact match first
if (availableLocales.includes(browserLang)) {
return browserLang;
}
// Try language code without region (e.g., 'en' from 'en-US')
const langCode = browserLang.split('-')[0];
if (availableLocales.includes(langCode)) {
return langCode;
}
// Try to find a locale that starts with the same language code
const matchingLocale = availableLocales.find((locale) => locale.toLowerCase().startsWith(langCode.toLowerCase()));
if (matchingLocale) {
return matchingLocale;
}
return null;
}
/**
* Check if we're in a browser environment
*/
export function isBrowser() {
return typeof window !== 'undefined' && typeof window.navigator !== 'undefined';
}