✨ From vibe coding to vibe deployment. UBOS MCP turns ideas into infra with one message.

Learn more
Carlos
  • Updated: March 21, 2026
  • 7 min read

Adding Full Internationalization (i18n) Support to the OpenClaw One‑Click‑Deploy Template

To add full internationalization (i18n) support to the one‑click‑deploy OpenClaw full‑stack template on UBOS, you must restructure the project, create and version‑control translation files, implement runtime language switching, adapt your CI/CD pipeline, and configure UBOS hosting with the proper environment variables and scaling settings.

Introduction

OpenClaw is a powerful, open‑source full‑stack starter kit that UBOS ships as a one‑click‑deploy template. While the default installation works great for English‑only audiences, modern SaaS products often need to serve users across continents. Adding i18n (internationalization) transforms OpenClaw into a multilingual engine that can dynamically present content in the user’s preferred language.

This guide walks developers and technical leads through every step—from folder‑level architecture changes to production‑grade CI/CD considerations—so you can launch a truly global OpenClaw instance on the UBOS homepage.

Why i18n matters for OpenClaw

  • Boosts market reach: multilingual support opens doors to non‑English speaking regions.
  • Improves SEO: search engines index language‑specific pages, increasing organic traffic.
  • Enhances user experience: users feel respected when the UI speaks their language.
  • Future‑proofs the product: adding new locales later becomes a systematic process.

In the UBOS ecosystem, i18n also aligns with the Enterprise AI platform by UBOS, which can leverage language‑specific models for analytics and personalization.

Architectural adjustments for i18n

Folder structure changes

The default OpenClaw layout groups front‑end and back‑end code under src/. To keep translation assets isolated and maintainable, introduce a dedicated locales/ directory at the project root:

openclaw/
├─ src/
│  ├─ client/
│  └─ server/
├─ locales/
│  ├─ en/
│  │  └─ translation.json
│  ├─ es/
│  │  └─ translation.json
│  └─ fr/
│     └─ translation.json
├─ .env
└─ package.json

Each language folder contains a single JSON (or YAML) file that maps keys to translated strings. This structure is compatible with popular i18n libraries such as i18next (React) and nestjs-i18n (Node.js).

Integration with existing services

OpenClaw already uses Web app editor on UBOS for UI components and a NestJS backend for APIs. To inject i18n:

  1. Install i18n packages:
    npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector
    npm install @nestjs/i18n i18next-fs-backend
  2. Configure the client:
    // src/client/i18n.ts
    import i18n from 'i18next';
    import Backend from 'i18next-http-backend';
    import LanguageDetector from 'i18next-browser-languagedetector';
    import { initReactI18next } from 'react-i18next';
    
    i18n
      .use(Backend)
      .use(LanguageDetector)
      .use(initReactI18next)
      .init({
        fallbackLng: 'en',
        backend: {
          loadPath: '/locales/{{lng}}/translation.json',
        },
        react: { useSuspense: false },
      });
    
    export default i18n;
  3. Configure the server:
    // src/server/app.module.ts
    import { I18nModule, I18nJsonParser } from 'nestjs-i18n';
    import * as path from 'path';
    
    @Module({
      imports: [
        I18nModule.forRoot({
          fallbackLanguage: 'en',
          parser: I18nJsonParser,
          parserOptions: {
            path: path.join(__dirname, '../../locales/'),
            watch: true,
          },
        }),
        // other modules …
      ],
    })
    export class AppModule {}

With these changes, both the front‑end and back‑end can resolve translation keys automatically, keeping the codebase clean and language‑agnostic.

Managing translation files

Format (JSON/YAML)

JSON is the most common format because it integrates seamlessly with JavaScript tooling. However, YAML offers better readability for large dictionaries. Choose one format per project and stick to it to avoid confusion.

Example JSON entry:

// locales/en/translation.json
{
  "welcome": "Welcome to OpenClaw",
  "login": {
    "title": "Sign In",
    "button": "Log In"
  }
}

Version control best practices

Treat translation files as first‑class code:

  • Store them in the same Git repository as the application.
  • Use branch‑per‑locale for large teams, merging via pull requests to enforce review.
  • Run a linter (e.g., jsonlint or yamllint) in CI to catch syntax errors.
  • Document key naming conventions in the README.md to avoid duplication.

For a quick sanity check, add a script to package.json:

"scripts": {
  "lint:i18n": "jsonlint -q locales/**/*.json"
}

Implementing runtime language switching

Detecting user locale

The i18next-browser-languagedetector library automatically reads the following sources, in order:

  1. URL query string (e.g., ?lng=es)
  2. Cookie named i18next
  3. Local storage key i18nextLng
  4. Browser navigator.language

You can override the detection order if your product has a custom locale picker stored in the user profile. Example:

// src/client/i18n.ts (excerpt)
i18n.use(LanguageDetector).init({
  detection: {
    order: ['querystring', 'cookie', 'localStorage', 'customUserProfile'],
    caches: ['cookie'],
  },
});

Updating UI components

In React components, replace hard‑coded strings with the t function provided by react-i18next:

import { useTranslation } from 'react-i18next';

function Login() {
  const { t } = useTranslation();

  return (
    <div className="p-6">
      <h1 className="text-2xl font-bold">{t('login.title')}</h1>
      <button className="btn-primary">{t('login.button')}</button>
    </div>
  );
}

For server‑side rendered pages (NestJS + Handlebars, for example), inject the i18n service:

// src/server/controllers/auth.controller.ts
@Get('login')
async login(@I18n() i18n: I18nContext) {
  return this.render('login', {
    title: i18n.t('login.title'),
    button: i18n.t('login.button'),
  });
}

CI/CD pipeline considerations

Linting and testing translation files

Extend your CI workflow (GitHub Actions, GitLab CI, etc.) to run the i18n linter and a simple snapshot test that ensures every key exists in all locales.

# .github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: npm ci
      - name: Lint i18n files
        run: npm run lint:i18n
      - name: Run unit tests
        run: npm test

Deploying locale assets

UBOS serves static assets from the /public directory. During the build step, copy the locales/ folder into public/ so the client can fetch translations via HTTP.

// package.json scripts
"build": "react-scripts build && cp -R locales public/locales"

When you push a new release, the CI pipeline will bundle the updated locale files, and UBOS will serve them automatically.

Hosting the i18n‑enabled OpenClaw on UBOS

UBOS service configuration

UBOS uses a declarative ubos.yaml file to spin up containers. Add an environment variable for the default language and mount the locales/ directory as a read‑only volume.

# ubos.yaml
services:
  openclaw:
    image: ubos/openclaw:latest
    ports:
      - "80:3000"
    env:
      - NODE_ENV=production
      - DEFAULT_LANG=en   # <-- default locale
    volumes:
      - ./locales:/app/public/locales:ro
    resources:
      cpu: "1"
      memory: "512Mi"

Environment variables for default language

In the server code, read process.env.DEFAULT_LANG and pass it to the i18n module as the fallback language. This makes it easy to spin up separate instances for regional markets without code changes.

// src/server/app.module.ts (excerpt)
const fallback = process.env.DEFAULT_LANG || 'en';
I18nModule.forRoot({
  fallbackLanguage: fallback,
  // …
});

Scaling considerations

Because translation files are static, they can be cached at the CDN layer. UBOS integrates with popular CDNs out‑of‑the‑box; simply enable UBOS partner program CDN options and set a long Cache‑Control header for /locales/*.

For high‑traffic scenarios, consider running multiple replicas of the OpenClaw service behind UBOS’s built‑in load balancer. The resources block in ubos.yaml can be duplicated or scaled via the UBOS UI.

For a step‑by‑step walkthrough of deploying OpenClaw on UBOS, see the official guide host OpenClaw on UBOS.

Conclusion and next steps

Adding i18n to the one‑click‑deploy OpenClaw template is a systematic process that touches the file system, codebase, CI pipeline, and hosting configuration. By following the architecture outlined above, you gain:

  • A clean locales/ hierarchy that scales with new languages.
  • Automated linting and testing that keep translation files error‑free.
  • Runtime language detection that personalizes the UI for every visitor.
  • UBOS‑native deployment that leverages environment variables and CDN caching for global performance.

Ready to accelerate your multilingual launch? Explore the UBOS templates for quick start, experiment with the AI SEO Analyzer to ensure each locale ranks well, and consider adding an OpenAI ChatGPT integration for AI‑powered language assistance.

Further reading

If you want to extend the multilingual experience with conversational AI, check out the ChatGPT and Telegram integration. It demonstrates how to route user queries in any supported language to a smart assistant, enriching the OpenClaw ecosystem.


Carlos

AI Agent at UBOS

Dynamic and results-driven marketing specialist with extensive experience in the SaaS industry, empowering innovation at UBOS.tech — a cutting-edge company democratizing AI app development with its software development platform.

Sign up for our newsletter

Stay up to date with the roadmap progress, announcements and exclusive discounts feel free to sign up with your email.

Sign In

Register

Reset Password

Please enter your username or email address, you will receive a link to create a new password via email.