#multi-lang paths
7 messages · Page 1 of 1 (latest)
To set up pages for each language, you can follow the steps mentioned in the Astro i18n recipe (https://docs.astro.build/en/recipes/i18n#set-up-pages-for-each-language). You'll need to create a directory for each language you want to support and place the corresponding pages inside those directories. For example, if you want to support English and French for your blog.astro page, you can create the following structure:
- src/
- pages/
- en/
- blog.astro
- index.astro
- fr/
- blog.astro
- index.astro
- index.astro
Then, you can use the getLangFromUrl (https://docs.astro.build/en/recipes/i18n#translate-ui-strings) function to get the language from the URL and set the lang attribute in your base layout. Here's an example of how to do this:
---
import { getLangFromUrl } from '../i18n/utils';
const lang = getLangFromUrl(Astro.url);
---
<html lang={lang}>
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<title>Astro</title>
</head>
<body>
<slot />
</body>
</html>
Finally, use the base layout in your blog.astro page:
---
import Base from "../../layouts/Base.astro"
---
<Base>
<h1>Blog</h1>
...
</Base>
This way, you can set up any other pages you have for each language by following the same structure and using the base layout.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@dark holly kapa.ai is still learning and improving, please let us how it did by reacting below
@dull chasm i'm using a slug like this:
---
import type { CollectionEntry } from 'astro:content'
import { getCollection } from 'astro:content'
import MainLayout from '../../layouts/MainLayout.astro'
import { getLangFromSlug, stripLangFromSlug } from '../../languages'
export async function getStaticPaths() {
const docsCollection = await getCollection('docs')
return docsCollection.map((page) => {
const lang = getLangFromSlug(page.slug)
const slug = stripLangFromSlug(page.slug)
return { params: { lang, slug }, props: page }
})
}
export async function getStaticProps(params: any) {
const docsCollection = await getCollection('docs')
const { lang, slug } = params
const page = docsCollection.find((entry) => {
return (
getLangFromSlug(entry.slug) === lang &&
stripLangFromSlug(entry.slug) === slug
)
})
return { props: { data: page } }
}
export type Props = CollectionEntry<'docs'>
const { data, render } = Astro.props
const { Content, headings } = await render()
---
<MainLayout {...{ data, headings }}>
<Content />
</MainLayout>
Then at the [lang]/index.astro i have this:
---
import MainLayout from '../../layouts/MainLayout.astro'
import languages from '../../i18n/languages'
export const getStaticPaths = () =>
Object.keys(languages).map((lang) => ({ params: { lang } }))
const { lang } = Astro.params
---
<MainLayout {lang}>
</MainLayout>
The this is that i have more pages that i want to translate using ht /content folder like this:
content/
<lang>/
blog/
portfolio/
Let me check the knowledge base for you. One moment! :books:
To set up translations for more pages using the /content folder, you can follow these steps:
- Organize your content in the
src/content/folder with subdirectories for each language and page type:
- src/
- content/
- en/
- blog/
- post-1.md
- post-2.md
- portfolio/
- project-1.md
- project-2.md
- fr/
- blog/
- post-1.md
- post-2.md
- portfolio/
- project-1.md
- project-2.md
- Create a
src/content/config.tsfile and export a collection for each type of content:
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
schema: z.object({
title: z.string(),
author: z.string(),
date: z.date(),
}),
});
const portfolioCollection = defineCollection({
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
}),
});
export const collections = {
'blog': blogCollection,
'portfolio': portfolioCollection,
};
- Use dynamic routes (https://docs.astro.build/en/core-concepts/routing/#dynamic-routes) to fetch and render content based on a
langand aslugparameter. For example, for theblogpage:
---
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const pages = await getCollection('blog')
const paths = pages.map(page => {
const [lang, ...slug] = page.slug.split('/');
return { params: { lang, slug: slug.join('/') || undefined }, props: page }
})
return paths;
}
const { lang, slug } = Astro.params;
const page = Astro.props;
const formattedDate = page.data.date.toLocaleString(lang);
const { Content } = await page.render();
---
<MainLayout {...{ data: page, headings }}>
<Content />
</MainLayout>
Repeat the process for the portfolio page, adjusting the collection name and other relevant details.