pull/3312/merge
Babak Farkhoopak 3 weeks ago committed by GitHub
commit 22934d24a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -154,6 +154,10 @@ export function createRouter(
} catch (e) {} } catch (e) {}
} }
if (siteDataRef.value.localesFallback) {
await loadFallback()
}
if (latestPendingPath === pendingPath) { if (latestPendingPath === pendingPath) {
latestPendingPath = null latestPendingPath = null
route.path = inBrowser ? pendingPath : withBase(pendingPath) route.path = inBrowser ? pendingPath : withBase(pendingPath)
@ -168,6 +172,77 @@ export function createRouter(
syncRouteQueryAndHash(targetLoc) syncRouteQueryAndHash(targetLoc)
} }
} }
async function loadFallback() {
const locales = siteDataRef.value.locales
for (const [key, value] of Object.entries(locales)) {
if (!value.fallback) continue
if (value.fallback === 'root') {
throw new Error(
`Invalid VitePress Config: A locale (${key}), cannot fall back to (root).`
)
}
if (key === value.fallback) {
throw new Error(
`Invalid VitePress Config: A locale (${key}), cannot have a fallback to itself.`
)
}
if (!Object.keys(locales).includes(value.fallback)) {
throw new Error(
`Invalid VitePress Config: A locale (${key}), cannot have a fallback to a non existing locale.`
)
}
}
// If the length is less than 2, it means there are no alternative locales to fallback to.
if (!locales || Object.keys(locales).length < 2) {
return
}
const nonRootLocales = Object.fromEntries(
Object.entries(locales).filter(([name]) => name !== 'root')
)
const failedLocaleKey =
Object.keys(nonRootLocales).find(
(lang) =>
pendingPath === `/${lang}` || pendingPath.startsWith(`/${lang}/`)
) || 'root'
if (failedLocaleKey !== 'root') {
const fallbackLang =
locales[failedLocaleKey].fallback ?? getCustomFallbackLang()
await loadPage(
pendingPath.replace(
`/${failedLocaleKey}`,
fallbackLang ? `/${fallbackLang}` : ''
),
scrollPosition,
true
)
} else {
const fallbackPath = getRootLocaleFallbackPath()
if (!fallbackPath) return
await loadPage(fallbackPath, scrollPosition, true)
}
function getCustomFallbackLang() {
const customFallbackLang = siteDataRef.value.localesDefaultFallback
if (customFallbackLang && customFallbackLang !== failedLocaleKey) {
return customFallbackLang
}
}
function getRootLocaleFallbackPath() {
const fallbackLang = locales['root'].fallback
if (!fallbackLang) return
if (pendingPath === '/') return `/${fallbackLang}`
const pathDivider = pendingPath.startsWith('/') ? '' : '/'
return `/${fallbackLang}${pathDivider}${pendingPath}`
}
}
} }
function syncRouteQueryAndHash( function syncRouteQueryAndHash(

@ -335,6 +335,8 @@ export async function resolveSiteData(
appearance: userConfig.appearance ?? true, appearance: userConfig.appearance ?? true,
themeConfig: userConfig.themeConfig || {}, themeConfig: userConfig.themeConfig || {},
locales: userConfig.locales || {}, locales: userConfig.locales || {},
localesFallback: userConfig.localesFallback ?? true,
localesDefaultFallback: userConfig.localesDefaultFallback,
scrollOffset: userConfig.scrollOffset ?? 134, scrollOffset: userConfig.scrollOffset ?? 134,
cleanUrls: !!userConfig.cleanUrls, cleanUrls: !!userConfig.cleanUrls,
contentProps: userConfig.contentProps, contentProps: userConfig.contentProps,

@ -54,6 +54,16 @@ export interface UserConfig<ThemeConfig = any>
locales?: LocaleConfig<ThemeConfig> locales?: LocaleConfig<ThemeConfig>
/**
* If a page isn't found in the current language, allow switching to another language as a backup.
*/
localesFallback?: boolean
/**
* Use a custom locale key to be used as a default fallback for all locales. Default is root.
*/
localesDefaultFallback?: string
router?: { router?: {
prefetchLinks?: boolean prefetchLinks?: boolean
} }

17
types/shared.d.ts vendored

@ -142,6 +142,14 @@ export interface SiteData<ThemeConfig = any> {
| string[] | string[]
| { selector: string | string[]; padding: number } | { selector: string | string[]; padding: number }
locales: LocaleConfig<ThemeConfig> locales: LocaleConfig<ThemeConfig>
/**
* If a page isn't found in the current language, allow switching to another language as a backup.
*/
localesFallback?: boolean
/**
* Use a custom locale key to be used as a default fallback for all locales. Default is root.
*/
localesDefaultFallback?: string
localeIndex?: string localeIndex?: string
contentProps?: Record<string, any> contentProps?: Record<string, any>
router: { router: {
@ -179,7 +187,14 @@ export interface LocaleSpecificConfig<ThemeConfig = any> {
export type LocaleConfig<ThemeConfig = any> = Record< export type LocaleConfig<ThemeConfig = any> = Record<
string, string,
LocaleSpecificConfig<ThemeConfig> & { label: string; link?: string } LocaleSpecificConfig<ThemeConfig> & {
label: string
link?: string
/**
* If the requested page isn't found in this language, switch to the same page in the specified language as a backup.
*/
fallback?: string
}
> >
export type AdditionalConfig<ThemeConfig = any> = export type AdditionalConfig<ThemeConfig = any> =

Loading…
Cancel
Save