Skip to content

Internationalization

Most of our paid themes come with built-in support for internationalization (i18n) (more themes to follow!). This allows you to easily translate your site into multiple languages. In addition to this fully loaded docs page, there are tons of comments and examples within the code itself to help you get up and running quickly.

Capabilities

  • Language switcher component that can be placed anywhere on the site (and in multiple locations if desired)
    • If only one language is in use, it auto-hides itself
    • Easily change the text used for each locale
  • Keystatic CMS support for multiple languages
  • Translate routes
  • Utility functions to:
    • Translate text
    • Filter content collections by locale
    • Format dates in the correct locale
    • Get the current locale from the current URL
    • & more

The i18n features are built on top of Astro’s built-in i18n support, with many additional utility functions and components to make it much easier to use. Like everything with Cosmic Themes, it is optional and only one language can easily be used.

Text Translation Usage

Say we have this text translation object in src/config/translationData.json.ts:

export const textTranslations = {
en: {
hero_text: "Everything you need for an amazing website.",
},
fr: {
hero_text: "Tout ce dont vous avez besoin pour un site Web incroyable.",
},
} as const;

You use it like:

import { useTranslations } from "@js/translationUtils";
const t = useTranslations("fr");
t("hero_text"); // this would be "Tout ce dont vous avez besoin pour un site Web incroyable."

Route Translation Usage

Say we have this route translation object in src/config/translationData.json.ts:

export const routeTranslations = {
en: {
aboutKey: "about",
},
fr: {
aboutKey: "a-propos",
},
} as const;

This is used by the language switcher such that if you are on the english “/about” route, and switch to french, it will go to the “/a-propos” route.

Content Collection Filtering

Content collection are setup like src/content/blog/en/ and src/content/blog/fr/. You can filter them like this:

import { filterCollectionByLanguage } from "@js/localeUtils";
const services = await getCollection("services", ({ data }) => {
// filter out draft services
return data.draft !== true;
});
// get rid of pages from other languages and remove locale from slug
const filteredServices = filterCollectionByLanguage(services, "fr");

or like this for blog posts specifically:

import { getAllPosts } from "@js/blogUtils";
// gets all blog post under src/content/blog/fr/
const posts = await getAllPosts("fr");

Using multiple languages

If you’re planning on two or more languages, you’ll need to do a few things to get started. For this example, I’m going to demonstrate changing it from “fr” to “de” (French to German) site translations.

Adjust i18n config

Edit the i18n object from the astro.config.mjs file to match whatever languages you plan on using. It should look like this at the start:

astro.config.mjs
// i18n configuration must match src/config/siteSettings.json.ts
i18n: {
defaultLocale: "en",
locales: ["en", "fr"],
routing: {
prefixDefaultLocale: false,
},
},

Change to:

astro.config.mjs
// i18n configuration must match src/config/siteSettings.json.ts
i18n: {
defaultLocale: "en",
locales: ["en", "de"],
routing: {
prefixDefaultLocale: false,
},
},

Adjust siteSettings.json.ts

Find this file at src/config/siteSettings.json.ts. Edit this to match your i18n config and correctly format dates.

siteSettings.json.ts
// The below locales need to match what you've put in your `astro.config.mjs` file
export const locales = ["en", "de"] as const;
export const defaultLocale = "en" as const;
// localeMap is used to map languages to their respective locales - used for formatDate function
export const localeMap = {
en: "en-US",
de: "de-DE",
};

Adjust keystatic config

If you’re using Keystatic, you’ll also need to edit the keystatic.config.tsx file. This file is used to define the collections and fields that will be used in the Keystatic CMS.

In keystatic.config.tsx you’ll see a collections object. Edit it to match the languages you’re using.

keystatic.config.tsx
collections: {
blogEN: Collections.Blog("en"),
blogDE: Collections.Blog("de"),
authors: Collections.Authors(""),
servicesEN: Collections.Services("en"),
servicesDE: Collections.Services("de"),
otherPagesEN: Collections.OtherPages("en"),
otherPagesDE: Collections.OtherPages("de"),
},

Change all fr pages to de

The easiest way to start this next part is to use the find and replace feature of your IDE. For VSCode use the shortcut Ctrl + Shift + F to open the search bar. Search for "fr" and replace with "de". This will get you a good start, but you’ll still need to do some manual work.

Now you need to change all fr folders to de. These include:

  • src/pages/fr/ to src/pages/de/
  • content collections like:
    • src/content/blog/fr/ to src/content/blog/de/
    • src/content/otherPages/fr/ to src/content/otherPages/de/
    • etc.
  • data file translations
    • fr object and import statements as necessary, defined in src/config/translationData.json.ts
  • text translations also in src/config/translationData.json.ts

Adjust text

Now you can go forth and adjust text to your liking! You can make liberal use of the text translation capability, or copy/paste components and hard-code the text in the new language. Completely up to you.

How to just use one language

This assumes you’ve already unzipped the file, run npm install, and npm run dev once to see it. For this example, I’m going to make the website only be in english.

Edit i18n config

Edit the i18n object from the astro.config.mjs file to only have one language. It should look like this at the start:

astro.config.mjs
// i18n configuration must match src/config/siteSettings.json.ts
i18n: {
defaultLocale: "en",
locales: ["en", "fr"],
routing: {
prefixDefaultLocale: false,
},
},

Here’s what an edit to use only English will look like.

astro.config.mjs
// i18n configuration must match src/config/siteSettings.json.ts
i18n: {
defaultLocale: "en",
locales: ["en"],
routing: {
prefixDefaultLocale: false,
},
},

Edit siteSettings.json.ts

Find this file at src/config/siteSettings.json.ts. This file holds some core settings for the site. In particular, a locales array and defaultLocale.

Here’s what it looks like at the start:

siteSettings.json.ts
// The below locales need to match what you've put in your `astro.config.mjs` file
export const locales = ["en", "fr"] as const;
export const defaultLocale = "en" as const;

Here’s what you might edit it to:

siteSettings.json.ts
// The below locales need to match what you've put in your `astro.config.mjs` file
export const locales = ["en"] as const;
export const defaultLocale = "en" as const;

Edit keystatic config

If you’re using Keystatic, you’ll also need to edit the keystatic.config.tsx file. This file is used to define the collections and fields that will be used in the Keystatic CMS.

In keystatic.config.tsx you’ll see a collections object. Remove any languages you’re not using. Here’s what it is at the start:

keystatic.config.tsx
collections: {
blogEN: Collections.Blog("en"),
blogFR: Collections.Blog("fr"),
authors: Collections.Authors(""),
servicesEN: Collections.Services("en"),
servicesFR: Collections.Services("fr"),
otherPagesEN: Collections.OtherPages("en"),
otherPagesFR: Collections.OtherPages("fr"),
},

Edit it to only use your default language you previously set. For example:

keystatic.config.tsx
collections: {
blogEN: Collections.Blog("en"),
authors: Collections.Authors(""),
servicesEN: Collections.Services("en"),
otherPagesEN: Collections.OtherPages("en"),
},

Remove all fr pages

You can now remove all the fr pages from the src/pages folder. Simply open up this directory, select the “fr” subfolder, and delete it. This deletes the actual routes so they do not get built with your site.

Don’t worry, everything in that fr folder is in the base src/pages directory. Everything left is for your default language.

Extras you can also remove

At this point, everything will work with just one language. However, there are some extra items still you can remove. Such as:

  • any content collection “fr” folders, like src/content/blog/fr/ and src/content/otherPages/fr/
  • fr object of dataTranslations constant defined in src/config/translationData.json.ts