UNPKG

@inlang/paraglide-js

Version:

[![NPM Downloads](https://img.shields.io/npm/dw/%40inlang%2Fparaglide-js?logo=npm&logoColor=red&label=npm%20downloads)](https://www.npmjs.com/package/@inlang/paraglide-js) [![GitHub Issues](https://img.shields.io/github/issues-closed/opral/paraglide-js?lo

162 lines 5.79 kB
import { getLocale } from "./get-locale.js"; import { clearLocaleCookieCache } from "./extract-locale-from-cookie.js"; import { localizeUrl } from "./localize-url.js"; import { customClientStrategies, isCustomStrategy } from "./strategy.js"; import { cookieDomain, cookieMaxAge, cookieName, getStrategyForUrl, isServer, localStorageKey, strategy, TREE_SHAKE_COOKIE_STRATEGY_USED, TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED, TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED, TREE_SHAKE_URL_STRATEGY_USED, } from "./variables.js"; /** * Navigates to the localized URL, or reloads the current page * * @param {string} [newLocation] The new location */ const navigateOrReload = (newLocation) => { if (newLocation) { // reload the page by navigating to the new url window.location.href = newLocation; } else { // reload the page to reflect the new locale window.location.reload(); } }; /** * @typedef {(newLocale: Locale, options?: { reload?: boolean }) => void | Promise<void>} SetLocaleFn */ /** * Set the locale. * * Updates the locale using your configured strategies (cookie, localStorage, URL, etc.). * By default, this reloads the page on the client to reflect the new locale. Reloading * can be disabled by passing `reload: false` as an option, but you'll need to ensure * the UI updates to reflect the new locale. * * If any custom strategy's `setLocale` function is async, then this function * will become async as well. * * @see https://paraglidejs.com/strategy * * @example * setLocale('en'); * * @example * setLocale('en', { reload: false }); * * @type {SetLocaleFn} */ export let setLocale = (newLocale, options) => { const optionsWithDefaults = { reload: true, ...options, }; // locale is already set // https://github.com/opral/inlang-paraglide-js/issues/430 /** @type {Locale | undefined} */ let currentLocale; try { currentLocale = getLocale(); } catch { // do nothing, no locale has been set yet. } /** @type {Array<Promise<void>>} */ const customSetLocalePromises = []; /** @type {string | undefined} */ let newLocation = undefined; let strategyToUse = strategy; if (!isServer && typeof window !== "undefined" && window.location?.href) { strategyToUse = getStrategyForUrl(window.location.href); } for (const strat of strategyToUse) { if (TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED && strat === "globalVariable") { // a default for a custom strategy to get started quickly // is likely overwritten by `defineSetLocale()` _locale = newLocale; } else if (TREE_SHAKE_COOKIE_STRATEGY_USED && strat === "cookie") { if (isServer || typeof document === "undefined" || typeof window === "undefined") { continue; } // set the cookie const cookieString = `${cookieName}=${newLocale}; path=/; max-age=${cookieMaxAge}`; document.cookie = cookieDomain ? `${cookieString}; domain=${cookieDomain}` : cookieString; clearLocaleCookieCache(); } else if (strat === "baseLocale") { // nothing to be set here. baseLocale is only a fallback continue; } else if (TREE_SHAKE_URL_STRATEGY_USED && strat === "url" && typeof window !== "undefined") { // route to the new url // // this triggers a page reload but a user rarely // switches locales, so this should be fine. // // if the behavior is not desired, the implementation // can be overwritten by `defineSetLocale()` to avoid // a full page reload. newLocation = localizeUrl(window.location.href, { locale: newLocale, }).href; } else if (TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED && strat === "localStorage" && typeof window !== "undefined") { // set the localStorage localStorage.setItem(localStorageKey, newLocale); } else if (isCustomStrategy(strat) && customClientStrategies.has(strat)) { const handler = customClientStrategies.get(strat); if (handler) { let result = handler.setLocale(newLocale); // Handle async setLocale if (result instanceof Promise) { result = result.catch((error) => { throw new Error(`Custom strategy "${strat}" setLocale failed.`, { cause: error, }); }); customSetLocalePromises.push(result); } } } } const runReload = () => { if (!isServer && optionsWithDefaults.reload && window.location && newLocale !== currentLocale) { navigateOrReload(newLocation); } }; if (customSetLocalePromises.length) { return Promise.all(customSetLocalePromises).then(() => { runReload(); }); } runReload(); return; }; /** * Overwrite the `setLocale()` function. * * Use this function to overwrite how the locale is set. For example, * modify a cookie, env variable, or a user's preference. * * @example * overwriteSetLocale((newLocale) => { * // set the locale in a cookie * return Cookies.set('locale', newLocale) * }); * * @param {SetLocaleFn} fn */ export const overwriteSetLocale = (fn) => { setLocale = fn; }; //# sourceMappingURL=set-locale.js.map