Skip to content

Commit

Permalink
feat: add sitemap (#7)
Browse files Browse the repository at this point in the history
Co-authored-by: Luiz Ferraz <[email protected]>
  • Loading branch information
florian-lefebvre and Fryuni authored Apr 11, 2024
1 parent d01908c commit 8bc6c8e
Show file tree
Hide file tree
Showing 44 changed files with 1,489 additions and 790 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-grapes-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrolicious/i18n": minor
---

Adds a new `getDefaultLocalePlaceholder` utility
5 changes: 5 additions & 0 deletions .changeset/strange-sloths-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrolicious/i18n": minor
---

Adds Content Collections helpers
5 changes: 5 additions & 0 deletions .changeset/swift-planets-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrolicious/i18n": minor
---

Adds sitemap support
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
}
},
"files": {
"ignore": ["dist", ".astro"]
"ignore": ["dist", ".astro", ".netlify"]
}
}
2 changes: 2 additions & 0 deletions demo/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ pnpm-debug.log*

# macOS-specific files
.DS_Store

.netlify
2 changes: 2 additions & 0 deletions demo/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import netlify from "@astrojs/netlify";

// https://astro.build/config
export default defineConfig({
site: "https://astro-i18n-demo.netlify.app",
integrations: [
i18n({
defaultLocale: "en",
Expand All @@ -28,6 +29,7 @@ export default defineConfig({
data: true,
paths: true,
},
sitemap: true,
}),
tailwind(),
react(),
Expand Down
3 changes: 2 additions & 1 deletion demo/src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ViewTransitions } from "astro:transitions";
import { getHtmlAttrs } from "i18n:astro";
import I18NClient from "@astrolicious/i18n/components/I18nClient.astro";
import I18NHead from "@astrolicious/i18n/components/I18nHead.astro";
import Header from "../components/Header.astro";
import Footer from "../components/Footer.astro";
import Header from "../components/Header.astro";
interface Props {
title: string;
Expand All @@ -20,6 +20,7 @@ const { title } = Astro.props;
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<link rel="sitemap" href="/sitemap-index.xml" />
<I18NHead />
<I18NClient />
<ViewTransitions />
Expand Down
2 changes: 1 addition & 1 deletion demo/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
"opensource": "Did you know that this page is available on GitHub? No? Well, now you know!",
"opensourceCTA": "Check it out!",
"blog": "Blog"
}
}
2 changes: 1 addition & 1 deletion demo/src/locales/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
"opensource": "Saviez-vous que cette page est disponible sur GitHub ? Non ? Eh bien, maintenant vous le savez !",
"opensourceCTA": "Allez y jeter un œil !",
"blog": "Le blog"
}
}
18 changes: 9 additions & 9 deletions demo/src/locales/it/common.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"home": "Home",
"hero": "Benvenuti alla demo di I18n per Astro",
"footer": "Fatto con il ❤️ da astrolicious",
"about": "Chi siamo",
"aboutMessage": "Questa è una pagina semplice",
"opensource": "Lo sapevi che questa pagina è disponibile su GitHub? No? Beh, ora lo sai!",
"opensourceCTA": "Vai a dare un'occhiata!",
"blog": "Blog"
}
"home": "Home",
"hero": "Benvenuti alla demo di I18n per Astro",
"footer": "Fatto con il ❤️ da astrolicious",
"about": "Chi siamo",
"aboutMessage": "Questa è una pagina semplice",
"opensource": "Lo sapevi che questa pagina è disponibile su GitHub? No? Beh, ora lo sai!",
"opensourceCTA": "Vai a dare un'occhiata!",
"blog": "Blog"
}
2 changes: 1 addition & 1 deletion demo/src/routes/about.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
import { t } from "i18n:astro";
import Layout from "~/layouts/Layout.astro";
import HeroMessage from "~/components/HeroMessage.astro";
import Layout from "~/layouts/Layout.astro";
const title = t("about");
---
Expand Down
84 changes: 46 additions & 38 deletions demo/src/routes/blog/[slug].astro
Original file line number Diff line number Diff line change
@@ -1,61 +1,69 @@
---
import { getCollection } from "astro:content";
import {
getDefaultLocale,
getLocale,
getDefaultLocalePlaceholder,
getLocalePlaceholder,
setDynamicParams,
t,
} from "i18n:astro";
import sitemap from "i18n:astro/sitemap";
import {
collectionFilters,
handleI18nSlug,
} from "@astrolicious/i18n/content-collections";
import type { GetStaticPaths } from "astro";
import Layout from "~/layouts/Layout.astro";
export const getStaticPaths = (async () => {
const locale = getLocalePlaceholder();
const defaultLocale = getDefaultLocalePlaceholder();
const posts = await getCollection(
"posts",
({ slug }) => slug.split("/")[0] === locale,
const posts = await getCollection("posts", (post) =>
collectionFilters.byLocale(post, { locale }),
);
return posts.map((post) => ({
params: {
slug: post.slug.split("/")[1],
},
props: {
post,
},
}));
}) satisfies GetStaticPaths;
return await Promise.all(
posts.map(async (post) => {
const equivalentPosts = await getCollection("posts", (p) =>
collectionFilters.matchingEntries(p, {
currentEntry: post,
key: "defaultLocaleVersion",
locale,
defaultLocale,
}),
);
const dynamicParams = equivalentPosts.map((entry) => {
const { locale, slug } = handleI18nSlug(entry.slug);
const locale = getLocale();
const defaultLocale = getDefaultLocale();
const { post } = Astro.props;
return {
locale,
params: {
slug,
},
};
});
const equivalentPosts = await getCollection("posts", (p) => {
if (locale === defaultLocale) {
return (
p.slug === post.slug || p.data.defaultLocaleVersion?.slug === post.slug
);
}
return (
p.slug === post.data.defaultLocaleVersion?.slug ||
p.data.defaultLocaleVersion?.slug === post.data.defaultLocaleVersion?.slug
sitemap({
dynamicParams,
});
return {
params: {
slug: handleI18nSlug(post.slug).slug,
},
props: {
post,
dynamicParams,
},
};
}),
);
});
}) satisfies GetStaticPaths;
setDynamicParams(
equivalentPosts.map((post) => {
const [locale, slug] = post.slug.split("/");
const { post, dynamicParams } = Astro.props;
return {
locale,
params: {
slug,
},
};
}),
);
setDynamicParams(dynamicParams);
const title = `${t("blog")} - ${post.data.title}`;
---
Expand Down
3 changes: 2 additions & 1 deletion demo/src/routes/index.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
import { t } from "i18n:astro";
import Layout from "~/layouts/Layout.astro";
import HeroMessage from "~/components/HeroMessage.astro";
import Layout from "~/layouts/Layout.astro";
const title = t("home");
---
Expand All @@ -10,6 +10,7 @@ const title = t("home");
<div class="justify-center items-center">
<HeroMessage message="hero" />
</div>
<p><a href="/sitemap-0.xml">Sitemap</a></p>
<script>
const data = await fetch("/api/hello").then(res => res.text())
console.log({ data })
Expand Down
6 changes: 6 additions & 0 deletions docs/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ export default defineConfig({
directory: "reference/components",
},
},
{
label: "Content collections",
autogenerate: {
directory: "reference/content-collections",
},
},
{
label: "Utilities",
autogenerate: {
Expand Down
5 changes: 0 additions & 5 deletions docs/src/content/docs/getting-started/known-issues.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ Translating rest parameters in your integration config `pages` option and using
`getLocalePath` and `switchLocalePath` **has not been tested yet**. Note that this is planned
and will be tackled soon.

## Sitemap

The official sitemap integration works but is not optimally integrated. The alternate links won't
be generated for different paths (eg. `/about`, `/fr/a-propos`). **This is being worked on**.

## Starlight

Usage in **Starlight** has not been tested but is not recommended, as it has its own i18n system.
10 changes: 6 additions & 4 deletions docs/src/content/docs/recipes/get-static-paths.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ title: getStaticPaths
routes but it runs before everything, even middlewares.

Under the hood, the package uses a middleware so we can't access any of the standard utilities inside
of `getStaticPaths`. Instead, we provide a `getLocalePlaceholder` function that is a build time macro.
of `getStaticPaths`. Instead, we provide `getLocalePlaceholder` and `getDefaultLocalePlaceholder` function that is a build time macro.
That means it will be replaced by it's literal value. For instance:

```astro
---
import { getLocalePlaceholder } from "i18n:astro"
import { getLocalePlaceholder, getDefaultLocalePlaceholder } from "i18n:astro"
export const getStaticPaths = () => {
const locale = getLocalePlaceholder()
const defaultLocale = getDefaultLocalePlaceholder()
return []
}
Expand All @@ -25,14 +26,15 @@ Will be replaced by the following, no matter the context:

```astro {5}
---
import { getLocalePlaceholder } from "i18n:astro"
import { getLocalePlaceholder, getDefaultLocalePlaceholder } from "i18n:astro"
export const getStaticPaths = () => {
const locale = "en"
const defaultLocale = "en"
return []
}
---
```

Be careful not to use `getLocalePlaceholder` in interpolations or it could result in invalid code.
Be careful not to use `getLocalePlaceholder` or `getDefaultLocalePlaceholder` in interpolations or it could result in invalid code.
89 changes: 89 additions & 0 deletions docs/src/content/docs/recipes/sitemap.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Sitemap
---

To enable the sitemap, set the `sitemap` option of the integration config to `true` or an object:

```ts title="astro.config.mjs" ins={3}
i18n({
// ...
sitemap: true // or {}
})
```

After you run `astro sync`, you'll be able to import a new function from `i18n:astro/sitemap` on your Astro pages:

```astro
---
import sitemap from "i18n:astro/sitemap"
---
```

This allows you to set specific params at the route level. It's really interesting to generate i18n friendly sitemaps (with alternates):

```ts
import { getCollection } from "astro:content";
import {
getLocalePlaceholder,
getDefaultLocalePlaceholder,
setDynamicParams,
} from "i18n:astro";
import sitemap from "i18n:astro/sitemap";
import {
collectionFilters,
generateDynamicParams,
handleI18nSlug,
} from "@astrolicious/i18n/content-collections";
import type { GetStaticPaths } from "astro";

export const getStaticPaths = (async () => {
const locale = getLocalePlaceholder();
const defaultLocale = getDefaultLocalePlaceholder();

const posts = await getCollection("posts", (post) =>
collectionFilters.byLocale(post, { locale }),
);

return await Promise.all(
posts.map(async (post) => {
const equivalentPosts = await getCollection("posts", (p) =>
collectionFilters.matchingEntries(p, {
currentEntry: post,
key: "defaultLocaleVersion",
locale,
defaultLocale,
}),
);

const dynamicParams = equivalentPosts.map((entry) => {
const { locale, slug } = handleI18nSlug(entry.slug);

return {
locale,
params: {
slug,
},
};
});

sitemap({
dynamicParams,
});

return {
params: {
slug: handleI18nSlug(post.slug).slug,
},
props: {
post,
dynamicParams,
},
};
}),
);
}) satisfies GetStaticPaths;

const { post, dynamicParams } = Astro.props;

setDynamicParams(dynamicParams);
```
Loading

0 comments on commit 8bc6c8e

Please sign in to comment.