Skip to Content
Internationalization

Internationalization

A Collection reads from ${contentDir}/${locale}/ whenever opts.locale is set. This makes it trivial to ship per-locale posts under the same defineCollection({...}) instance.

content/ blog/ en/ welcome.md fr/ welcome.md

Reading per locale

import { blog } from '@/next-md-blog.config'; const enPosts = await blog.getAll({ locale: 'en' }); const post = await blog.getOne('welcome', { locale: 'fr' });

Hreflang

// Map every sibling translation of `slug` to its locale-aware URL. const map = await blog.hreflangMap('welcome', ['en', 'fr', 'es']); // → { en: 'https://…/en/blog/welcome', fr: 'https://…/fr/blog/welcome' } return blog.metadata(post, { locale, titleTemplate: 'absolute', // bypass parent layout's `%s | Site` template alternateLanguages: map, });

Per-post overrides via frontmatter.alternateLanguages (a Record<hreflang, url>) win over the computed map.

Sitemap with hreflang

Pass every supported locale to sitemapEntries or composeSitemap — each row gets an xhtml:link rel="alternate" hreflang per locale that has a translation, plus x-default.

import { composeSitemap } from '@next-md-blog/core'; import { blog, glossary } from '@/next-md-blog.config'; export default async function sitemap() { return composeSitemap({ collections: [blog, glossary], locales: ['en', 'fr', 'es'], }); }

Static params

const LOCALES = ['en', 'fr', 'es'] as const; export async function generateStaticParams() { const out: Array<{ slug: string; locale: string }> = []; for (const locale of LOCALES) { const posts = await blog.getAll({ locale }); for (const p of posts) out.push({ slug: p.slug, locale }); } return out; }

Per-locale RSS

app/[lang]/feed.xml/route.ts
import { blog, LOCALES } from '@/next-md-blog.config'; export async function generateStaticParams() { return LOCALES.map((lang) => ({ lang })); } export async function GET(_req: Request, { params }: { params: Promise<{ lang: string }> }) { const { lang } = await params; return blog.rssResponse({ locale: lang }); }

Reference implementation

The i18n demo at demo.i18n.next-md-blog.com  wires every step end-to-end (see Demos).

Deploy the i18n template on Vercel

Deploy with Vercel

Single-locale starter: Deploy with Vercel

Last updated on