71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
type LocalizedRouteTarget = string | {
|
|
path?: string
|
|
name?: string
|
|
params?: Record<string, unknown>
|
|
query?: Record<string, unknown>
|
|
hash?: string
|
|
}
|
|
|
|
// This composable is used in route middleware, where `useI18n()` is not available.
|
|
const LOCALE_CODES = ['ru', 'en']
|
|
|
|
function normalizePath(path: string) {
|
|
return path || '/'
|
|
}
|
|
|
|
export function stripLocalePrefix(path: string, localeCodes: string[]) {
|
|
const normalizedPath = normalizePath(path)
|
|
const localePattern = localeCodes.map(code => code.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')
|
|
|
|
if (!localePattern) return normalizedPath
|
|
|
|
const match = normalizedPath.match(new RegExp(`^/(${localePattern})(?=/|$)`))
|
|
if (!match) return normalizedPath
|
|
|
|
const nextPath = normalizedPath.slice(match[0].length)
|
|
return nextPath || '/'
|
|
}
|
|
|
|
export function useLocalizedNavigation() {
|
|
const route = useRoute()
|
|
const localePath = useLocalePath()
|
|
const basePath = computed(() => stripLocalePrefix(route.path, LOCALE_CODES))
|
|
|
|
function toLocalized(to: LocalizedRouteTarget) {
|
|
if (typeof to === 'string') {
|
|
return to.startsWith('/') ? localePath(to) : to
|
|
}
|
|
|
|
if (to.path) {
|
|
return {
|
|
...to,
|
|
path: to.path.startsWith('/') ? localePath(to.path) : to.path,
|
|
}
|
|
}
|
|
|
|
return to
|
|
}
|
|
|
|
function isBasePathActive(target: string, exact = false) {
|
|
const normalizedTarget = normalizePath(target)
|
|
|
|
if (exact) {
|
|
return basePath.value === normalizedTarget
|
|
}
|
|
|
|
return basePath.value === normalizedTarget || basePath.value.startsWith(`${normalizedTarget}/`)
|
|
}
|
|
|
|
function navigateToLocalized(to: LocalizedRouteTarget, options?: Parameters<typeof navigateTo>[1]) {
|
|
return navigateTo(toLocalized(to), options)
|
|
}
|
|
|
|
return {
|
|
basePath,
|
|
isBasePathActive,
|
|
localePath,
|
|
navigateToLocalized,
|
|
toLocalized,
|
|
}
|
|
}
|