Commit b3c86a9
Changed files (4)
src
components
layouts
pages
[locale]
posts
src/components/widgets/LocaleSwitcher.astro
@@ -6,9 +6,13 @@ import {
type Locale,
} from "intlayer";
-import { SITE_CONFIG } from "@/config.ts";
import { getPathWithoutLocale, getRelativeLocaleUrl } from "@/utils/url.ts";
+interface Props {
+ availableLocales: Locale[];
+}
+
+const { availableLocales } = Astro.props;
const locale = Astro.currentLocale;
const globalI18n = getIntlayer("global", locale);
const currentPath = Astro.url.pathname;
@@ -22,7 +26,7 @@ const getLocaleUrl = (target: Locale) =>
onchange="location.href = this.value"
>
{
- SITE_CONFIG.locales.map((target) => (
+ availableLocales.map((target) => (
<option
value={getLocaleUrl(target)}
selected={target === locale}
src/components/Header.astro
@@ -1,11 +1,16 @@
---
-import { getIntlayer } from "intlayer";
+import { getIntlayer, type Locale } from "intlayer";
import { SITE_CONFIG } from "@/config.ts";
import { getRelativeLocaleUrl, url } from "@/utils/url.ts";
import LocaleSwitcher from "@/components/widgets/LocaleSwitcher.astro";
+interface Props {
+ availableLocales: Locale[];
+}
+
+const { availableLocales } = Astro.props;
const locale = Astro.currentLocale!;
const globalI18n = getIntlayer("global", locale);
---
@@ -18,7 +23,7 @@ const globalI18n = getIntlayer("global", locale);
<li><a href={getRelativeLocaleUrl("/about", locale)}>{globalI18n.about}</a></li>
<li><a href={url("/feed.atom")}>{globalI18n.feed}</a></li>
</ul>
- <LocaleSwitcher />
+ <LocaleSwitcher availableLocales={availableLocales} />
</nav>
</header>
src/layouts/BaseLayout.astro
@@ -15,6 +15,7 @@ interface Props {
title?: string;
author?: string;
description?: string;
+ availableLocales?: Locale[];
ogType?: "website" | "article";
}
@@ -25,9 +26,20 @@ const {
title = SITE_CONFIG.title,
author = SITE_CONFIG.author,
description = globalI18n.description,
+ availableLocales = SITE_CONFIG.locales,
ogType = "website",
} = Astro.props;
+const pageLocales = SITE_CONFIG.locales.filter((candidate) =>
+ availableLocales.includes(candidate)
+);
+
+if (!pageLocales.includes(DEFAULT_LOCALE)) {
+ throw new Error(
+ `Page ${Astro.url.pathname} must be built for the default locale "${DEFAULT_LOCALE}".`,
+ );
+}
+
const getAbsoluteLocaleUrl = (
path: string,
locale: Locale,
@@ -56,7 +68,7 @@ const getAbsoluteLocaleUrl = (
<meta name="author" content={author} />
{
- SITE_CONFIG.locales.map((target) => (
+ pageLocales.map((target) => (
<link rel="alternate" hreflang={target}
href={getAbsoluteLocaleUrl(getPathWithoutLocale(Astro.url.pathname), target)}
>
@@ -78,7 +90,7 @@ const getAbsoluteLocaleUrl = (
<Font cssVariable="--font-stix-two-math" />
</head>
<body>
- <Header />
+ <Header availableLocales={pageLocales} />
<main>
<slot />
</main>
src/pages/[locale]/posts/[slug].astro
@@ -16,6 +16,10 @@ export const getStaticPaths = (async () => {
const postsLocaleMap = getPostsLocaleMap(posts);
return Object.entries(postsLocaleMap).flatMap(([slug, localeMap]) => {
+ const availableLocales = SITE_CONFIG.locales.filter((locale) =>
+ localeMap[locale] !== undefined
+ );
+
return SITE_CONFIG.locales.map((locale) => {
const entry = localeMap[locale];
if (entry === undefined) {
@@ -23,14 +27,14 @@ export const getStaticPaths = (async () => {
} else {
return {
params: { locale, slug },
- props: { entry },
+ props: { entry, availableLocales },
};
}
}).filter((i) => i !== undefined);
});
}) satisfies GetStaticPaths;
-const { entry } = Astro.props;
+const { entry, availableLocales } = Astro.props;
const data = entry.data;
const { Content } = await render(entry);
@@ -39,6 +43,7 @@ const { Content } = await render(entry);
title={data.title}
author={data.author}
description={data.desc}
+ availableLocales={availableLocales}
ogType="article"
>
<article>