Eight specialized detector modules for different browser APIs and storage mechanisms. Each detector implements a consistent interface for language lookup and optional caching, providing flexibility to extend the detection system with custom implementations.
Interface that all detector modules must implement for integration with the detection system.
interface CustomDetector {
/** Unique name for the detector */
name: string;
/**
* Language detection implementation
* @param options - Configuration options from DetectorOptions
* @returns Detected language code(s) or undefined if none found
*/
lookup(options: DetectorOptions): string | string[] | undefined;
/**
* Optional caching implementation
* @param lng - Language code to cache
* @param options - Configuration options from DetectorOptions
*/
cacheUserLanguage?(lng: string, options: DetectorOptions): void;
}Detects language from browser cookies with support for reading and writing cookie values.
// Built-in detector: 'cookie'
interface CookieDetector {
name: 'cookie';
lookup(options: DetectorOptions): string | undefined;
cacheUserLanguage(lng: string, options: DetectorOptions): void;
}How it works:
options.lookupCookieoptions.cookieMinutesoptions.cookieDomainoptions.cookieOptionsdocument.cookieUsage Examples:
// Configure cookie detection
const options = {
lookupCookie: 'user_language',
cookieMinutes: 60 * 24 * 30, // 30 days
cookieDomain: '.example.com',
cookieOptions: {
secure: true,
sameSite: 'strict'
}
};
// Manual cookie detection
detector.detect(['cookie']); // Only use cookie detectionDetects language from URL query parameters, supporting both standard query strings and hash-based parameters.
// Built-in detector: 'querystring'
interface QueryStringDetector {
name: 'querystring';
lookup(options: DetectorOptions): string | undefined;
}How it works:
options.lookupQuerystringwindow.location.hash?lng=en#/page?lng=en?lang=fr-CAUsage Examples:
// Configure querystring detection
const options = {
lookupQuerystring: 'lang' // Look for ?lang=en instead of ?lng=en
};
// URLs that would be detected:
// https://example.com?lang=en -> 'en'
// https://example.com#/route?lang=fr -> 'fr'
// https://example.com/page?lang=zh-CN -> 'zh-CN'Detects and caches language in browser localStorage with availability checking.
// Built-in detector: 'localStorage'
interface LocalStorageDetector {
name: 'localStorage';
lookup(options: DetectorOptions): string | undefined;
cacheUserLanguage(lng: string, options: DetectorOptions): void;
}How it works:
options.lookupLocalStorageUsage Examples:
// Configure localStorage detection
const options = {
lookupLocalStorage: 'app_language',
caches: ['localStorage'] // Enable caching to localStorage
};
// localStorage key will be 'app_language'
// Value persists across browser sessionsDetects and caches language in browser sessionStorage with availability checking.
// Built-in detector: 'sessionStorage'
interface SessionStorageDetector {
name: 'sessionStorage';
lookup(options: DetectorOptions): string | undefined;
cacheUserLanguage(lng: string, options: DetectorOptions): void;
}How it works:
options.lookupSessionStorageUsage Examples:
// Configure sessionStorage detection
const options = {
lookupSessionStorage: 'session_lang',
caches: ['sessionStorage'] // Enable caching to sessionStorage
};
// sessionStorage key will be 'session_lang'
// Value cleared when browser tab is closedDetects language from browser navigator object, supporting multiple browser language APIs.
// Built-in detector: 'navigator'
interface NavigatorDetector {
name: 'navigator';
lookup(options: DetectorOptions): string[] | undefined;
}How it works:
navigator.languagesnavigator.userLanguagenavigator.languageUsage Examples:
// Navigator detection returns language arrays
const detected = detector.detect(['navigator']);
// Example result: ['en-US', 'en', 'fr']
// Handles different browser implementations:
// Chrome: navigator.languages = ['en-US', 'en']
// IE: navigator.userLanguage = 'en-US'
// Safari: navigator.language = 'en-US'Detects language from HTML lang attribute on specified elements.
// Built-in detector: 'htmlTag'
interface HtmlTagDetector {
name: 'htmlTag';
lookup(options: DetectorOptions): string | undefined;
}How it works:
langoptions.htmlTagdocument.documentElementUsage Examples:
// Use default document element
const defaultOptions = {}; // Uses document.documentElement
// Use specific element
const customOptions = {
htmlTag: document.querySelector('#app')
};
// Disable HTML tag detection
const disabledOptions = {
htmlTag: null
};
// Example HTML:
// <html lang="en-US"> -> 'en-US'
// <div id="app" lang="fr"> -> 'fr' (if configured)Detects language from URL path segments using configurable indexing.
// Built-in detector: 'path'
interface PathDetector {
name: 'path';
lookup(options: DetectorOptions): string | undefined;
}How it works:
window.location.pathnameoptions.lookupFromPathIndex/language-code/Usage Examples:
// Configure path detection
const options = {
lookupFromPathIndex: 0 // Use first path segment
};
// Example URLs:
// /en/home -> 'en'
// /fr-CA/products -> 'fr-CA'
// /zh/about/contact -> 'zh'
// Use second segment
const secondSegmentOptions = {
lookupFromPathIndex: 1
};
// /app/en/dashboard -> 'en' (second segment)Detects language from hostname subdomains using pattern matching and indexing.
// Built-in detector: 'subdomain'
interface SubdomainDetector {
name: 'subdomain';
lookup(options: DetectorOptions): string | undefined;
}How it works:
window.location.hostnameen.example.comfr.localhostoptions.lookupFromSubdomainIndexUsage Examples:
// Configure subdomain detection
const options = {
lookupFromSubdomainIndex: 0 // Use first subdomain
};
// Example hostnames:
// en.example.com -> 'en'
// fr.myapp.localhost -> 'fr'
// de.api.service.com -> 'de' (first subdomain)
// Use different subdomain position
const secondSubdomainOptions = {
lookupFromSubdomainIndex: 1
};
// api.en.example.com -> 'en' (second subdomain)Implement the
CustomDetector// Example: Detect language from user API preferences
const apiDetector: CustomDetector = {
name: 'userApi',
async lookup(options) {
try {
const response = await fetch('/api/user/preferences');
const data = await response.json();
return data.language;
} catch (error) {
return undefined; // Return undefined on error
}
},
async cacheUserLanguage(lng, options) {
try {
await fetch('/api/user/preferences', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ language: lng })
});
} catch (error) {
// Handle error silently
}
}
};
// Add to detector
detector.addDetector(apiDetector);
// Use in detection order
detector.init(null, {
order: ['userApi', 'cookie', 'navigator']
});All built-in detectors are designed to fail gracefully:
undefineddocumentwindowstringstring[]undefined