Fixed support for multi-langual slugs
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import type { I18nConfig } from './types.js'
|
||||
|
||||
import { isValidLocale } from './helpers.js'
|
||||
|
||||
/**
|
||||
@@ -12,14 +11,22 @@ import { isValidLocale } from './helpers.js'
|
||||
export type LocalizedSlugs = Record<string, string>
|
||||
|
||||
type BuildPathArgs = {
|
||||
config: I18nConfig
|
||||
/**
|
||||
* Slug that represents the site root (served at /{locale} with no trailing
|
||||
* segment). Defaults to 'home'. Matched against the slug in the target locale.
|
||||
*/
|
||||
homeSlug?: string
|
||||
/** slug per locale, e.g. { pl: 'strona-glowna', en: 'home' } */
|
||||
slugs: LocalizedSlugs
|
||||
/** Target locale to build the path for */
|
||||
locale: string
|
||||
config: I18nConfig
|
||||
/**
|
||||
* Slug(s) representing the site root (served at /{locale} with no trailing
|
||||
* segment). Defaults to 'home'. Matched against the slug in the target locale.
|
||||
*
|
||||
* Can be a single string (same home slug in every locale) OR a per-locale map
|
||||
* (`{ pl: 'strona-glowna', de: 'startseite', en: 'home' }`). The map form is
|
||||
* REQUIRED for multilingual homepages whose slug differs per language —
|
||||
* otherwise the home page collapses to '/pl' but '/de/startseite' stays
|
||||
* un-collapsed, breaking hreflang return tags (a real GSC error).
|
||||
*/
|
||||
homeSlug?: string | Record<string, string>
|
||||
/**
|
||||
* Localized segment the document lives under, e.g.
|
||||
* `{ pl: 'artykuly', en: 'articles' }` → /pl/artykuly/moj-post.
|
||||
@@ -29,8 +36,6 @@ type BuildPathArgs = {
|
||||
* A document under a prefix is never the home page, so homeSlug is ignored.
|
||||
*/
|
||||
prefix?: LocalizedSlugs
|
||||
/** slug per locale, e.g. { pl: 'strona-glowna', en: 'home' } */
|
||||
slugs: LocalizedSlugs
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,11 +61,11 @@ type BuildPathArgs = {
|
||||
* // → '/en/articles/my-post'
|
||||
*/
|
||||
export function buildLocalizedPath({
|
||||
slugs,
|
||||
locale,
|
||||
config,
|
||||
homeSlug = 'home',
|
||||
locale,
|
||||
prefix,
|
||||
slugs,
|
||||
}: BuildPathArgs): string | undefined {
|
||||
if (!isValidLocale(locale, config)) {
|
||||
return undefined
|
||||
@@ -89,7 +94,13 @@ export function buildLocalizedPath({
|
||||
return `${localeSegment}/${segment}/${slug}`
|
||||
}
|
||||
|
||||
if (slug === homeSlug) {
|
||||
// Resolve the home slug for THIS locale. With a per-locale map, each language
|
||||
// has its own home slug (pl: 'strona-glowna', de: 'startseite'), so the check
|
||||
// below correctly collapses each language's home to its root — instead of only
|
||||
// the current-language slug matching and the others staying un-collapsed.
|
||||
const targetHomeSlug = typeof homeSlug === 'object' ? homeSlug[locale] : homeSlug
|
||||
|
||||
if (slug === targetHomeSlug) {
|
||||
// Home collapses to the root: '/' for single-locale, '/pl' otherwise.
|
||||
return localeSegment || '/'
|
||||
}
|
||||
@@ -98,11 +109,11 @@ export function buildLocalizedPath({
|
||||
}
|
||||
|
||||
type SwitchLocaleArgs = {
|
||||
config: I18nConfig
|
||||
homeSlug?: string
|
||||
prefix?: LocalizedSlugs
|
||||
slugs: LocalizedSlugs
|
||||
targetLocale: string
|
||||
config: I18nConfig
|
||||
homeSlug?: string | Record<string, string>
|
||||
prefix?: LocalizedSlugs
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,17 +125,17 @@ type SwitchLocaleArgs = {
|
||||
* to the locale root otherwise — the closest place the visitor would want.
|
||||
*/
|
||||
export function switchLocalePath({
|
||||
slugs,
|
||||
targetLocale,
|
||||
config,
|
||||
homeSlug = 'home',
|
||||
prefix,
|
||||
slugs,
|
||||
targetLocale,
|
||||
}: SwitchLocaleArgs): string {
|
||||
const path = buildLocalizedPath({ config, homeSlug, locale: targetLocale, prefix, slugs })
|
||||
if (path) {return path}
|
||||
const path = buildLocalizedPath({ slugs, locale: targetLocale, config, homeSlug, prefix })
|
||||
if (path) return path
|
||||
|
||||
const archiveSegment = prefix?.[targetLocale]
|
||||
if (archiveSegment) {return `/${targetLocale}/${archiveSegment}`}
|
||||
if (archiveSegment) return `/${targetLocale}/${archiveSegment}`
|
||||
|
||||
return `/${targetLocale}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user