Improve localized page path resolution
SteamWar CI / Build (push) Successful in 1m53s
SteamWar CI / Deploy (push) Successful in 10s

- Resolve page locale from source paths instead of IDs
- Deduplicate localized fallback paths and pass page descriptions to layout
This commit is contained in:
2026-05-24 10:55:25 +02:00
parent 413c84e293
commit 167992769e
+42 -12
View File
@@ -1,46 +1,76 @@
--- ---
import { getCollection, render, type CollectionEntry } from "astro:content"; 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 PageLayout from "../layouts/PageLayout.astro";
import LanguageWarning from "../components/LanguageWarning.astro"; import LanguageWarning from "../components/LanguageWarning.astro";
import "@styles/table.css"; import "@styles/table.css";
export const getStaticPaths = createGetStaticPaths(async () => { export const getStaticPaths = createGetStaticPaths(async () => {
const allPages = await getCollection("pages"); 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) => { return match?.[1] ?? page.id.split("/")[0] ?? astroI18n.primaryLocale;
if (posts.find((post) => post.id.split("/")[1] !== value.id.split("/")[1])) { }
posts.push(value);
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 { function fixLink(page: CollectionEntry<"pages">): string {
if (astroI18n.locale != astroI18n.primaryLocale && Object.keys(page.data.slugs ?? {}).includes(astroI18n.locale)) { if (locale !== astroI18n.primaryLocale) {
return page.data.slugs[astroI18n.locale]; 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: { props: {
page, page,
german: astroI18n.locale !== astroI18n.primaryLocale && page.id.split("/")[0] !== astroI18n.locale, german: locale !== astroI18n.primaryLocale && getPageLocale(page) !== locale,
}, },
params: { params: {
slug: fixLink(page), slug: fixLink(page),
}, },
})); }));
const uniquePaths = new Map<string, (typeof paths)[number]>();
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 { page, german } = Astro.props as { page: CollectionEntry<"pages">; german: boolean };
const { Content } = await render(page); const { Content } = await render(page);
--- ---
<PageLayout title={page.data.title}> <PageLayout title={page.data.title} description={page.data.description}>
<article> <article>
{german && <LanguageWarning />} {german && <LanguageWarning />}
<h1 class="text-left" style="font-family: 'Barlow Condensed', sans-serif; letter-spacing: 0.04em;">{page.data.title}</h1> <h1 class="text-left" style="font-family: 'Barlow Condensed', sans-serif; letter-spacing: 0.04em;">{page.data.title}</h1>