DeepWiki Internationalization: How Multi-Language Support Works
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 contains English strings, while 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, the application loads 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 at lines 49-51 serves this configuration:
@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 (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 defines the list of supported locales and returns a Next-Intl request configuration that dynamically imports the appropriate message bundle.
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:
- Configuration Fetch: The
LanguageProvidercomponent requests/api/lang/configto retrieve supported languages and the default locale. - Browser Detection: The
detectBrowserLanguage()function extracts the two-letter language code fromnavigator.language. If the code exists in the supported locales list (imported fromsrc/i18n.ts), it is selected; otherwise the default"en"is chosen. - Bundle Loading: The provider dynamically imports
../messages/${validLanguage}.jsonand stores the translation object in React state. - Context Availability: Components throughout the application access translations via the
useLanguagehook, which reads from theLanguageContext.
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.
Creating a Language Selector
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
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:
- Register the locale in
src/i18n.ts:
export const locales = [
'en', 'ja', 'zh', 'es', 'kr', 'vi', 'pt-br', 'de'
];
- Update the server configuration in
config/lang.json:
{
"supported_languages": {
"en": "English",
"ja": "日本語 (Japanese)",
"de": "Deutsch (German)"
},
"default": "en"
}
- Create the translation file at
src/messages/de.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 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, whilesrc/i18n.tsandsrc/contexts/LanguageContext.tsxhandle dynamic loading and browser detection. - The backend exposes supported languages via the
/lang/configendpoint defined inapi/api.py(lines 49-51), driven byconfig/lang.json. - Components access translations through the
useLanguagehook, which providesmessages,language, andsetLanguage. - 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 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 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. 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →