https://github.com/openscript/astro-loader-i18n
An Astro glob content loader for i18n files and folder structures. ๐
https://github.com/openscript/astro-loader-i18n
astro content-loader i18n
Last synced: 7 months ago
JSON representation
An Astro glob content loader for i18n files and folder structures. ๐
- Host: GitHub
- URL: https://github.com/openscript/astro-loader-i18n
- Owner: openscript
- License: mit
- Created: 2025-02-16T08:52:36.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-06-20T14:42:22.000Z (7 months ago)
- Last Synced: 2025-06-21T10:06:38.119Z (7 months ago)
- Topics: astro, content-loader, i18n
- Language: TypeScript
- Homepage:
- Size: 1.13 MB
- Stars: 8
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# astro-loader-i18n
This package is a simple content loader for i18n files and folder structures, partially built on top of the [`glob()` loader](https://docs.astro.build/en/reference/content-loader-reference/#glob-loader).
```bash
npm install astro-loader-i18n
```
```bash
yarn add astro-loader-i18n
```
```bash
pnpm add astro-loader-i18n
```
## Overview
For example, given the following i18n structure:
```
. (project root)
โโโ README.md
โโโ src
โโโ content
โโโ pages
โโโ de-CH
โ โโโ about.mdx
โ โโโ projects.mdx
โโโ zh-CN
โโโ about.mdx
โโโ projects.mdx
```
Define a collection in your `content.config.ts` using the `astro-loader-i18n` file:
```typescript
import { i18nFolderLoader, z } from 'astro-loader-i18n';
import { defineCollection } from 'astro:content';
const pages = defineCollection({
loader: i18nFolderLoader({
pattern: "**/*.mdx",
base: "src/content/pages",
schema: z.object({
title: z.string(),
}),
}),
schema: /* USUALLY YOU DON'T WANT TO OVERRIDE THE LOADERS SCHEMA */
});
export const collections = { pages };
```
> [!CAUTION]
> The `schema` should be defined in the loader, not in the collection definition. This is because the loader is responsible for parsing the content and the collection is responsible for filtering and sorting the content.
Retrieve the collection and filter by locale:
```ts
import { getCollection } from "astro:content";
const pages = await getCollection("pages", (entry) => { entry.locale === "de-CH"});
```
## Usage
This loader supports differently structured localized content:
### Folder via `i18nFolderLoader`
The content is structured into locales by folders:
```
. (project root)
โโโ README.md
โโโ src
โโโ content
โโโ pages
โโโ de-CH
โ โโโ about.mdx
โ โโโ projects.mdx
โโโ zh-CN
โโโ about.mdx
โโโ projects.mdx
```
- The locale is determined by the folder name.
- Localized subfolders can be used to structure the content further.
- Page translations need to be separately mapped.
- Useful for:
- Individual pages with multiple translations
- Flat content structures
### Files via `i18nFilesLoader`
```
. (project root)
โโโ src
โโโ content
โโโ pages
โโโ about.de-CH.mdx
โโโ about.zh-CN.mdx
โโโ projects.de-CH.mdx
โโโ projects.zh-CN.mdx
```
- The locale is determined by the file name suffix.
- Subfolders can be used to structure the content further.
- Subfolder names need to be separately translated.
- Useful for:
- Blogs
- News
- Articles
- Notes
- ...
### Infile via standard `glob()` loader
```
. (project root)
โโโ src
โโโ content
โโโ navigation
โโโ footer.yml
โโโ main.yml
```
```yaml
# src/content/navigation/main.yml
de-CH:
- path: /projekte
title: Projekte
- path: /ueber-mich
title: รber mich
zh-CN:
- path: /zh/projects
title: ้กน็ฎ
- path: /zh/about-me
title: ๅ
ณไบๆ
```
- The locale is determined by the key in the YAML file.
- The content is structured in a single file.
- This allows sharing untranslated content across locales.
- Useful for:
- Menus
- Galleries
- ...
## Improvements
- [ ] Export `GlobOptions` type from Astro