Skip to main content

Implementing Internationalization (i18n) on a Docusaurus Site

This article outlines the steps to implement the internationalization (i18n) feature on a Docusaurus site, enabling content switching between Japanese (default) and English.

Based on the official documentation, this guide also includes practical tips such as commands for a Docker environment and reliable methods for verification before deployment.

Prerequisites:

  • Site Generator: Docusaurus (project already set up)
  • Development Environment: Docker (commands for a local environment are also provided)
  • Goal: Support two languages: Japanese (ja) and English (en)

Sources

1. Update Docusaurus Configuration File (docusaurus.config.ts)

First, enable the i18n feature in Docusaurus and configure the basic site settings.

  1. Open the docusaurus.config.ts (or .js) file in your project root.

  2. Add an i18n object to define the default language and the languages your site will support. It is also recommended to set trailingSlash: true for URL normalization. This ensures stable routing regardless of the server environment.

    docusaurus.config.ts
    // docusaurus.config.ts
    import type {Config} from '@docusaurus/types';

    const config: Config = {
    // ...

    // Force a trailing slash on URLs for stable routing
    trailingSlash: true,

    i18n: {
    // The site's default language
    defaultLocale: 'ja',
    // A list of languages the site supports
    locales: ['ja', 'en'],
    // Detailed configuration for each language (for the language switcher label and HTML lang attribute)
    localeConfigs: {
    ja: {
    label: '日本語',
    htmlLang: 'ja-JP',
    },
    en: {
    label: 'English',
    htmlLang: 'en-US',
    },
    },
    },

    // ...
    };
  3. Add type: 'localeDropdown' to themeConfig.navbar.items to display a language switcher in the header, allowing users to switch languages on the site.

    docusaurus.config.ts
    // docusaurus.config.ts
    // ...
    themeConfig: {
    navbar: {
    items: [
    // ... (existing navigation items)

    // Add the language switcher
    {
    type: 'localeDropdown',
    position: 'right', // Can also be 'left'
    },
    ],
    },
    // ...
    },
    // ...

2. Generate and Translate UI Files

Next, create translation files for common UI elements used across the site (e.g., "Previous" and "Next" page buttons).

  1. Run the command to generate translation files Execute the following command in your terminal to generate translation templates (JSON files) for the additional language (in this case, English: en) in the i18n/en/ directory.

    # For Docker environments
    docker-compose run --rm app pnpm write-translations --locale en

    # For local environments
    pnpm docusaurus write-translations --locale en
  2. Translate UI Text Open the generated JSON files, such as i18n/en/docusaurus-theme-classic/code.json, and edit the values corresponding to the "message" key with the appropriate English translations.

3. Place Translated Content (Most Important Step)

This is the most critical step in the i18n process. Place the translated Markdown files in the correct directory structure that Docusaurus can recognize.

  1. Create Directories for Translated Content It's convenient to create the directories for the additional language (English) content all at once from your host machine's terminal.

    # Create directories for English content for docs, blog, and pages
    mkdir -p i18n/en/docusaurus-plugin-content-docs/current \
    i18n/en/docusaurus-plugin-content-blog \
    i18n/en/docusaurus-plugin-content-pages

    ※ If you use multiple blog instances, create directories for each (e.g., docusaurus-plugin-content-blog-diary)

  2. Copy and Translate Content

    Advice

    It is highly recommended to start by translating just one page to quickly confirm that the i18n feature is working correctly.

    Example: Translating docs/intro.md into English

    1. Copy the file: Copy the default language file docs/intro.md to the English directory you just created.
      cp docs/intro.md i18n/en/docusaurus-plugin-content-docs/current/intro.md
    2. Translate the content: Open the destination file (i18n/en/.../intro.md) and rewrite all the Markdown content in English.

    Repeat this process for all other content you want to translate (blog posts, custom pages, etc.).

4. Verify the Setup

Check that the settings have been applied correctly. It's important to use two different methods: real-time checks during development and final checks before deployment.

4.1. Real-time Verification During Development

Use this method when you want to check the display of a specific language with hot reloading enabled, such as during translation work.

Note

The development server (start command) can only serve one language at a time. Also, the --host 0.0.0.0 option is required for external access in a Docker environment.

# 【To develop with the English site】
# Docker environment:
docker-compose run --rm --service-ports app pnpm start --locale en --host 0.0.0.0
# Local environment:
pnpm start --locale en

# 【To develop with the Japanese site (default)】
# Docker environment:
docker-compose run --rm --service-ports app pnpm start --host 0.0.0.0
# Local environment:
pnpm start

4.2. Final Verification Before Deployment

To prevent issues after deployment, perform a final check using the same build artifacts as in production, but in your local environment.

  1. Install an SPA-aware server (first time only) To replicate production routing issues locally, add http-server to your project.
    pnpm add -D http-server
  2. Configure the serve script (first time only) In your package.json, add a command to the scripts section to serve the build artifacts in SPA mode (--single).
    package.json
    "scripts": {
    // ...
    "build": "docusaurus build",
    "serve": "http-server ./build --single"
    }
  3. Build and Run the Preview This procedure is the most reliable final check before deployment.
    # 1. Build content for all languages
    pnpm build

    # 2. Preview with a production-like server
    pnpm serve
  4. Verify in the browser Access http://localhost:8080 (or the address shown in your terminal) in your browser. Thoroughly check that the language switcher works correctly across the entire site and that page navigation does not result in broken URLs or a blank screen.

5. Deployment

Once the final local verification is complete, deploy the generated build directory to your production hosting environment (e.g., Google Cloud Run, Vercel, Netlify). If you are using automated deployment with GitHub Actions, commit all your changes and merge them into the branch that triggers deployment (e.g., main).