@intlayer/core
Version:
Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.
94 lines (92 loc) • 5.77 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
const require_utils_checkIsURLAbsolute = require('../utils/checkIsURLAbsolute.cjs');
const require_localization_getPathWithoutLocale = require('./getPathWithoutLocale.cjs');
const require_localization_getPrefix = require('./getPrefix.cjs');
const require_localization_rewriteUtils = require('./rewriteUtils.cjs');
let _intlayer_config_built = require("@intlayer/config/built");
//#region src/localization/getLocalizedUrl.ts
/** Strips the protocol and returns the bare hostname of a domain string. */
const extractHostname = (domain) => {
try {
return /^https?:\/\//.test(domain) ? new URL(domain).hostname : domain;
} catch {
return domain;
}
};
/**
* Generate URL by prefixing the given URL with the referenced locale or adding search parameters
* based on the routing mode. Handles both absolute and relative URLs appropriately.
*
* This function gets the locales, default locale, and routing mode from the configuration if not provided.
*
* Example:
*
* ```ts
* // prefix-no-default mode
* getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });
* // Returns '/fr/about' for the French locale
* // Returns '/about' for the English locale (default)
*
* // prefix-all mode
* getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });
* // Returns '/en/about' for the English locale
* // Returns '/fr/about' for the French locale
*
* // search-params mode
* getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });
* // Returns '/about?locale=fr' for the French locale
*
* // no-prefix mode
* getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });
* // Returns '/about' for any locale
* ```
*
* @param url - The original URL string to be processed.
* @param currentLocale - The current locale.
* @param options - Configuration options
* @param options.locales - Optional array of supported locales. Defaults to configured locales.
* @param options.defaultLocale - The default locale. Defaults to configured default locale.
* @param options.mode - URL routing mode for locale handling. Defaults to configured mode.
* @param options.currentDomain - Hostname of the page being rendered. Used to decide
* whether to emit a relative URL (same domain) or an absolute URL (cross-domain).
* Auto-detected from the input URL or `window.location` when omitted.
* @returns The localized URL for the current locale.
*/
/**
* The return type is narrowed to a template-literal type when both `url` and
* `currentLocale` are string literals and the routing mode / defaultLocale are
* not overridden via `options`.
*/
const getLocalizedUrl = (url, currentLocale = _intlayer_config_built.internationalization?.defaultLocale, options = {}) => {
const { defaultLocale, mode, locales, rewrite, domains, currentDomain } = require_localization_getPrefix.resolveRoutingConfig(options);
const urlWithoutLocale = require_localization_getPathWithoutLocale.getPathWithoutLocale(url, locales);
const rewriteRules = require_localization_rewriteUtils.getRewriteRules(rewrite, "url");
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "no-prefix") && mode === "no-prefix") return require_localization_rewriteUtils.getLocalizedPath(require_localization_rewriteUtils.getCanonicalPath(urlWithoutLocale, void 0, rewriteRules), currentLocale, rewriteRules).path;
const isAbsoluteUrl = require_utils_checkIsURLAbsolute.checkIsURLAbsolute(urlWithoutLocale);
const parsedUrl = isAbsoluteUrl ? new URL(urlWithoutLocale) : new URL(urlWithoutLocale, "http://example.com");
const translatedPathname = require_localization_rewriteUtils.getLocalizedPath(require_localization_rewriteUtils.getCanonicalPath(parsedUrl.pathname, void 0, rewriteRules), currentLocale, rewriteRules).path;
const detectedCurrentHostname = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? extractHostname(currentDomain ?? (isAbsoluteUrl ? parsedUrl.hostname : void 0) ?? (typeof window !== "undefined" ? window?.location?.hostname : void 0) ?? "") || null : null;
const localeDomain = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? domains?.[currentLocale] : void 0;
const localeDomainHostname = localeDomain ? extractHostname(localeDomain) : null;
const normalizedDomain = localeDomainHostname !== null && detectedCurrentHostname !== null && localeDomainHostname !== detectedCurrentHostname && localeDomain ? /^https?:\/\//.test(localeDomain) ? localeDomain : `https://${localeDomain}` : null;
const baseUrl = normalizedDomain ? normalizedDomain : isAbsoluteUrl ? `${parsedUrl.protocol}//${parsedUrl.host}` : "";
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "search-params") && mode === "search-params") {
const searchParams = new URLSearchParams(parsedUrl.search);
searchParams.set("locale", currentLocale.toString());
const queryParams = searchParams.toString();
return `${baseUrl}${queryParams ? `${translatedPathname}?${queryParams}` : translatedPathname}${parsedUrl.hash}`;
}
const { prefix } = require_localization_getPrefix.getPrefix(currentLocale, {
defaultLocale,
mode,
locales,
domains
});
let localizedPath = `/${prefix}${translatedPathname}`.replace(/\/+/g, "/");
if (localizedPath.length > 1 && localizedPath.endsWith("/")) localizedPath = localizedPath.slice(0, -1);
return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;
};
//#endregion
exports.getLocalizedUrl = getLocalizedUrl;
//# sourceMappingURL=getLocalizedUrl.cjs.map