feat: fall back if translation is missing

pull/3312/head
babakfp 2 years ago
parent 006fd80095
commit 577d0791da

@ -74,7 +74,14 @@ export function createRouter(
let latestPendingPath: string | null = null
async function loadPage(href: string, scrollPosition = 0, isRetry = false) {
async function loadPage(
href: string,
scrollPosition = 0,
isRetry = false,
alreadyTriedLoadingRootFallback = false
) {
let fallbackLoaded = false
if ((await router.onBeforePageLoad?.(href)) === false) return
const targetLoc = new URL(href, fakeHost)
const pendingPath = (latestPendingPath = targetLoc.pathname)
@ -149,13 +156,98 @@ export function createRouter(
} catch (e) {}
}
if (latestPendingPath === pendingPath) {
if (!alreadyTriedLoadingRootFallback) {
fallbackLoaded = await loadPageFallback()
}
if (!fallbackLoaded && latestPendingPath === pendingPath) {
latestPendingPath = null
route.path = inBrowser ? pendingPath : withBase(pendingPath)
route.component = fallbackComponent ? markRaw(fallbackComponent) : null
route.data = notFoundPageData
}
}
// If failed to find the page, maybe it's not translated yet! if so, please fallback :)
async function loadPageFallback() {
const locales = siteDataRef.value.locales
if (!locales) return fallbackLoaded
const namedLocales = Object.fromEntries(
Object.entries(siteDataRef.value.locales).filter(
([name]) => name !== 'root'
)
)
if (!Object.entries(namedLocales).length) return fallbackLoaded
const langNames = Object.keys(namedLocales)
const failedLang = langNames.find(
(lang) =>
pendingPath === `/${lang}` || pendingPath.startsWith(`/${lang}/`)
)
if (failedLang) {
const fallbackLang =
getFailedLangFallbackLang() ?? getCustomFallbackLang()
if (fallbackLang) {
await loadPage(
pendingPath.replace(`/${failedLang}`, `/${fallbackLang}`)
)
return fallbackLoaded
} else {
await loadPage(pendingPath.replace(`/${failedLang}`, ''))
return fallbackLoaded
}
} else {
const rootRouteFallbackPath = getRootRouteFallbackPath()
if (rootRouteFallbackPath) {
await loadPage(rootRouteFallbackPath, 0, true, true)
}
return fallbackLoaded
}
function getFailedLangFallbackLang() {
const failedLangFallbackLang = locales[failedLang!]?.fallback
if (!failedLangFallbackLang) return
if (!langNames.includes(failedLangFallbackLang)) {
console.warn(
`No keys in 'locales' with the name of 'locales.${failedLang}.fallback'! RECIVED '${failedLangFallbackLang}'`
)
return
}
return failedLangFallbackLang
}
function getCustomFallbackLang() {
const customFallbackLang = Object.entries(namedLocales).filter(
([_, values]) => values.useAsFallback
)?.[0]?.[0]
if (customFallbackLang && customFallbackLang !== failedLang) {
return customFallbackLang
}
}
function getRootRouteFallbackPath() {
const fallbackLang = locales['root']?.fallback
if (!fallbackLang) return
if (!langNames.includes(fallbackLang)) {
console.warn(
`No keys in 'locales' with the name of 'locales.root.fallback'! RECIVED '${fallbackLang}'`
)
return
}
return pendingPath === '/'
? `/${fallbackLang}`
: `/${fallbackLang}${
pendingPath.startsWith('/') ? pendingPath : `/${pendingPath}`
}`
}
}
}
if (inBrowser) {

7
types/shared.d.ts vendored

@ -156,7 +156,12 @@ export interface LocaleSpecificConfig<ThemeConfig = any> {
export type LocaleConfig<ThemeConfig = any> = Record<
string,
LocaleSpecificConfig<ThemeConfig> & { label: string; link?: string }
LocaleSpecificConfig<ThemeConfig> & {
label: string
link?: string
fallback?: string
useAsFallback?: boolean
}
>
// Manually declaring all properties as rollup-plugin-dts

Loading…
Cancel
Save