From 167992769e9e5065d4cd1abec003eb2312ff77b5 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 24 May 2026 10:55:25 +0200 Subject: [PATCH] Improve localized page path resolution - Resolve page locale from source paths instead of IDs - Deduplicate localized fallback paths and pass page descriptions to layout --- src/pages/[...slug].astro | 54 ++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro index 6698542..c908ff3 100644 --- a/src/pages/[...slug].astro +++ b/src/pages/[...slug].astro @@ -1,46 +1,76 @@ --- import { getCollection, render, type CollectionEntry } from "astro:content"; -import { astroI18n, createGetStaticPaths, stripLocaleFromPath } from "$lib/i18n"; +import { astroI18n, createGetStaticPaths, l, stripLocaleFromPath } from "$lib/i18n"; import PageLayout from "../layouts/PageLayout.astro"; import LanguageWarning from "../components/LanguageWarning.astro"; import "@styles/table.css"; export const getStaticPaths = createGetStaticPaths(async () => { const allPages = await getCollection("pages"); - let posts = allPages.filter((value) => value.id.split("/")[0] === astroI18n.locale); + const locale = astroI18n.locale; - const germanPosts = allPages.filter((entry) => entry.id.split("/")[0] === astroI18n.fallbackLocale); + function getPageLocale(page: CollectionEntry<"pages">): string { + const sourcePath = page.filePath ?? ""; + const match = sourcePath.match(/(?:^|[/\\])src[/\\]content[/\\]pages[/\\]([^/\\]+)/); - germanPosts.forEach((value) => { - if (posts.find((post) => post.id.split("/")[1] !== value.id.split("/")[1])) { - posts.push(value); + return match?.[1] ?? page.id.split("/")[0] ?? astroI18n.primaryLocale; + } + + const posts = allPages.filter((page) => getPageLocale(page) === locale); + + const germanPosts = allPages.filter((page) => getPageLocale(page) === astroI18n.fallbackLocale); + + germanPosts.forEach((page) => { + const fallbackSlug = fixLink(page); + + if (!posts.some((post) => fixLink(post) === fallbackSlug)) { + posts.push(page); } }); function fixLink(page: CollectionEntry<"pages">): string { - if (astroI18n.locale != astroI18n.primaryLocale && Object.keys(page.data.slugs ?? {}).includes(astroI18n.locale)) { - return page.data.slugs[astroI18n.locale]; + if (locale !== astroI18n.primaryLocale) { + const translatedSlug = page.data.slugs?.[locale]; + + if (translatedSlug) { + return translatedSlug; + } } - return page.data.slug ?? stripLocaleFromPath(page.id); + const slug = page.data.slug ?? stripLocaleFromPath(page.id); + + if (locale !== astroI18n.primaryLocale && getPageLocale(page) === astroI18n.primaryLocale) { + return stripLocaleFromPath(l(`/${slug}`, undefined, { targetLocale: locale })); + } + + return slug; } - return posts.map((page) => ({ + const paths = posts.map((page) => ({ props: { page, - german: astroI18n.locale !== astroI18n.primaryLocale && page.id.split("/")[0] !== astroI18n.locale, + german: locale !== astroI18n.primaryLocale && getPageLocale(page) !== locale, }, params: { slug: fixLink(page), }, })); + + const uniquePaths = new Map(); + paths.forEach((path) => { + if (!uniquePaths.has(path.params.slug)) { + uniquePaths.set(path.params.slug, path); + } + }); + + return Array.from(uniquePaths.values()); }); const { page, german } = Astro.props as { page: CollectionEntry<"pages">; german: boolean }; const { Content } = await render(page); --- - +
{german && }

{page.data.title}