UNPKG

remix-i18next

Version:

The easiest way to translate your Full Stack React Router apps

66 lines (54 loc) 1.85 kB
import { formatLanguageString } from "./format-language-string.js"; import { parse, pick } from "./parser.js"; export type Locales = string | string[] | undefined; /** * Get the client's locales from the Accept-Language header. * If the header is not defined returns null. * If the header is defined return an array of locales, sorted by the quality * value. * * @example * export let loader: LoaderFunction = async ({ request }) => { * let locales = getClientLocales(request) * let date = new Date().toLocaleDateString(locales, { * "day": "numeric", * }); * return json({ date }) * } */ export function getClientLocales(headers: Headers): Locales; export function getClientLocales(request: Request): Locales; export function getClientLocales(requestOrHeaders: Request | Headers): Locales { let headers = getHeaders(requestOrHeaders); let acceptLanguage = headers.get("Accept-Language"); // if the header is not defined, return undefined if (!acceptLanguage) return undefined; let parsedLocales = parse(acceptLanguage) .filter((lang) => lang.code !== "*") .map(formatLanguageString); let validLocales: string[] = []; for (let locale of parsedLocales) { try { // This will throw on invalid locales new Intl.Locale(locale); // If we get here, the locale is valid validLocales.push(locale); } catch { // We want to ignore errors here } } let locale = pick( Intl.DateTimeFormat.supportedLocalesOf(validLocales), acceptLanguage, ); return locale ?? undefined; } /** * Receives a Request or Headers objects. * If it's a Request returns the request.headers * If it's a Headers returns the object directly. */ function getHeaders(requestOrHeaders: Request | Headers): Headers { if (requestOrHeaders instanceof Request) return requestOrHeaders.headers; return requestOrHeaders; }