# DeepWiki Internationalization: How Multi-Language Support Works

> Discover DeepWiki internationalization. Learn how its data-driven React architecture dynamically loads JSON translation bundles for multi-language support, powering nine languages.

- Repository: [ASYNCFUNC/deepwiki-open](https://github.com/asyncfuncai/deepwiki-open)
- Tags: internals
- Published: 2026-02-16

---

**DeepWiki provides full internationalization (i18n) support through a data-driven React architecture that dynamically loads JSON translation bundles based on browser detection and user preference, supporting nine languages including English, Japanese, Chinese, and Spanish.**

DeepWiki is an open-source wiki generator that ships with comprehensive DeepWiki internationalization capabilities out of the box. The application implements a three-layer i18n stack that separates static translation data from runtime detection logic, making it straightforward to add new languages without modifying core application code.

## The Three-Layer DeepWiki i18n Architecture

DeepWiki’s internationalization system is organized into three coordinated layers that handle static assets, server-side configuration, and client-side runtime detection.

### Static Language Data (JSON Message Bundles)

All UI translations reside in `src/messages/*.json` files. Each file maps translation keys to localized strings for a specific locale. For example, [`en.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/en.json) contains English strings, while [`ja.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/ja.json) holds Japanese translations.

This static approach allows translators to work independently by editing JSON files without touching React components or Python backend code.

### Server-Side Language Configuration

The backend exposes supported languages through a centralized configuration system. In [`api/config.py`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/api/config.py), the application loads [`config/lang.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/config/lang.json) into `configs["lang_config"]`, which contains the list of supported languages and the default locale.

The FastAPI endpoint defined in [`api/api.py`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/api/api.py) at lines 49-51 serves this configuration:

```python
@router.get("/lang/config")
def get_lang_config():
    return configs["lang_config"]

```

The frontend accesses this endpoint at runtime to determine which languages are available. The rewrite rule in [`next.config.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/next.config.ts) (lines 62-65) ensures that requests to `/api/lang/config` are properly proxied to the backend server.

### Client-Side Runtime Detection

The React frontend handles dynamic language loading through two key files. [`src/i18n.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/i18n.ts) defines the list of supported locales and returns a Next-Intl request configuration that dynamically imports the appropriate message bundle.

[`src/contexts/LanguageContext.tsx`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/contexts/LanguageContext.tsx) implements the core detection logic. It fetches `/api/lang/config`, detects the browser’s preferred language using `navigator.language`, and dynamically imports the matching JSON file from `../messages/${validLanguage}.json`. The context exposes `language`, `setLanguage`, `messages`, and `supportedLanguages` to the entire component tree via the `useLanguage` hook.

## How DeepWiki Detects and Loads Languages

When a user opens DeepWiki, the following workflow executes:

1. **Configuration Fetch**: The `LanguageProvider` component requests `/api/lang/config` to retrieve supported languages and the default locale.
2. **Browser Detection**: The `detectBrowserLanguage()` function extracts the two-letter language code from `navigator.language`. If the code exists in the supported locales list (imported from [`src/i18n.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/i18n.ts)), it is selected; otherwise the default `"en"` is chosen.
3. **Bundle Loading**: The provider dynamically imports `../messages/${validLanguage}.json` and stores the translation object in React state.
4. **Context Availability**: Components throughout the application access translations via the `useLanguage` hook, which reads from the `LanguageContext`.

When users manually switch languages via `setLanguage`, the process repeats steps 3-4 and also updates `localStorage` for persistence and the `<html lang>` attribute for accessibility.

## Implementing Language Switching in React Components

Components can read and modify the current language using the `useLanguage` hook provided by [`src/contexts/LanguageContext.tsx`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/contexts/LanguageContext.tsx).

### Creating a Language Selector

```tsx
import { useLanguage } from '@/contexts/LanguageContext';

export default function LanguageSwitcher() {
  const { language, setLanguage, supportedLanguages } = useLanguage();

  return (
    <select
      value={language}
      onChange={e => setLanguage(e.target.value)}
    >
      {Object.entries(supportedLanguages).map(([code, name]) => (
        <option key={code} value={code}>
          {name}
        </option>
      ))}
    </select>
  );
}

```

### Accessing Translated Strings

```tsx
import { useLanguage } from '@/contexts/LanguageContext';

export default function Header() {
  const { messages } = useLanguage();
  
  return (
    <h1>{messages['app.title'] ?? 'Deep Wiki'}</h1>
  );
}

```

The `messages` object contains the entire JSON translation bundle loaded dynamically from `src/messages/`, allowing components to reference keys safely using the nullish coalescing operator for fallbacks.

## Adding a New Language to DeepWiki

DeepWiki’s data-driven architecture allows adding new languages without modifying core logic. To add German (de), for example:

1. **Register the locale** in [`src/i18n.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/i18n.ts):

```typescript
export const locales = [
  'en', 'ja', 'zh', 'es', 'kr', 'vi', 'pt-br', 'de'
];

```

2. **Update the server configuration** in [`config/lang.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/config/lang.json):

```json
{
  "supported_languages": {
    "en": "English",
    "ja": "日本語 (Japanese)",
    "de": "Deutsch (German)"
  },
  "default": "en"
}

```

3. **Create the translation file** at [`src/messages/de.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/messages/de.json):

```json
{
  "app.title": "Deep Wiki",
  "app.description": "Erstelle automatisch eine Wiki für jedes GitHub‑Repository."
}

```

No further code modifications are needed; the application automatically lists "Deutsch (German)" in the language selector and loads [`de.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/de.json) when selected.

## Summary

- DeepWiki provides complete **DeepWiki internationalization** support through a three-layer architecture separating static JSON assets, server-side configuration, and client-side React context.
- Translation files reside in `src/messages/*.json`, while [`src/i18n.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/i18n.ts) and [`src/contexts/LanguageContext.tsx`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/contexts/LanguageContext.tsx) handle dynamic loading and browser detection.
- The backend exposes supported languages via the `/lang/config` endpoint defined in [`api/api.py`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/api/api.py) (lines 49-51), driven by [`config/lang.json`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/config/lang.json).
- Components access translations through the `useLanguage` hook, which provides `messages`, `language`, and `setLanguage`.
- Adding new languages requires only three data files—no code changes—making DeepWiki’s i18n system fully extensible.

## Frequently Asked Questions

### Does DeepWiki support right-to-left (RTL) languages?

DeepWiki’s i18n infrastructure supports any language defined in the configuration files, but RTL layout handling depends on CSS implementation in the React components. The `LanguageContext` updates the `<html lang>` attribute, which can be used with CSS logical properties or libraries like `rtl-css-js` to handle text direction. However, the core message loading system in [`src/contexts/LanguageContext.tsx`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/contexts/LanguageContext.tsx) treats RTL and LTR languages identically.

### How does DeepWiki handle fallback languages when a translation key is missing?

When a translation key is not found in the loaded `messages` object, DeepWiki relies on the consuming component to provide fallback behavior. The typical pattern uses the nullish coalescing operator (`??`) to provide default text, as shown in `messages['app.title'] ?? 'Deep Wiki'`. The system does not automatically cascade to a default language file; instead, it loads only the active locale’s JSON bundle from `src/messages/` and expects complete key coverage within that file.

### Can I use DeepWiki’s i18n system with Next.js App Router?

The current implementation uses a custom `LanguageProvider` context in [`src/contexts/LanguageContext.tsx`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/contexts/LanguageContext.tsx) that fetches configuration from `/api/lang/config` and manages state via React hooks. While this works with Next.js Pages Router, adapting it for the App Router would require moving the detection logic to a Server Component or using the `next-intl` library’s App Router configuration in [`src/i18n.ts`](https://github.com/AsyncFuncAI/deepwiki-open/blob/main/src/i18n.ts). The static JSON files in `src/messages/` remain compatible with both routing strategies.

### What is the performance impact of dynamic message loading in DeepWiki?

DeepWiki uses dynamic imports to load only the active language bundle, keeping the initial JavaScript payload small. The `LanguageContext` caches the loaded messages in React state, preventing redundant fetches when components re-render. The `/api/lang/config` endpoint returns a small JSON object, and the system stores the user’s preference in `localStorage` to avoid re-detection on subsequent visits. This architecture ensures that adding new languages to `src/messages/` does not increase the bundle size for users who do not select those languages.