Skip to main content
RapidDev - Software Development Agency
replit-tutorial

How to support multiple languages in Replit apps

Add multi-language support to Replit apps using i18n libraries like react-i18next for React projects or Flask-Babel for Python. Create locale JSON files for each language, wire up a language switcher component, and let users toggle between languages at runtime. All configuration happens in code — no special Replit features are needed beyond the standard workspace.

What you'll learn

  • How to set up react-i18next for multi-language React apps on Replit
  • How to create and organize translation files for each supported language
  • How to build a language switcher component that persists user preferences
  • How to set up Flask-Babel for Python backend internationalization
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read25 minutesAll Replit plans. Works with React (react-i18next), Flask (Flask-Babel), and other frameworks. Install packages via Shell.March 2026RapidDev Engineering Team
TL;DR

Add multi-language support to Replit apps using i18n libraries like react-i18next for React projects or Flask-Babel for Python. Create locale JSON files for each language, wire up a language switcher component, and let users toggle between languages at runtime. All configuration happens in code — no special Replit features are needed beyond the standard workspace.

Add multi-language support to your Replit application

Internationalization (i18n) lets your app display content in multiple languages, making it accessible to a global audience. On Replit, you implement i18n the same way as any web project — using established libraries like react-i18next for React apps or Flask-Babel for Python Flask apps. This tutorial walks you through setting up translation files, configuring the i18n library, building a language switcher, and organizing locale files so your app scales cleanly as you add more languages.

Prerequisites

  • A Replit account with a React or Flask project
  • Basic understanding of React components or Flask route handlers
  • Familiarity with JSON file format (translations are stored as JSON)
  • Access to the Shell pane for installing npm/pip packages

Step-by-step guide

1

Install the i18n library for your framework

Open the Shell pane and install the appropriate internationalization library. For React projects, install react-i18next and i18next, which are the most widely used i18n solution in the React ecosystem. For Flask projects, install Flask-Babel. These libraries handle translation loading, language detection, pluralization, and formatting. Install them as regular dependencies since they are needed in production.

typescript
1# For React projects
2npm install i18next react-i18next i18next-browser-languagedetector
3
4# For Flask projects
5pip install Flask-Babel

Expected result: The packages install successfully and appear in package.json (React) or can be imported in Python (Flask).

2

Create translation files for each language

Create a directory structure to hold your translations. The standard pattern is to create a locales or translations folder with a subfolder or file for each language code (en, es, fr, de, etc.). Each file contains a flat or nested JSON object mapping translation keys to translated strings. Start with English as your base language and add other languages as needed. Keep translation keys descriptive and organized by feature or page.

typescript
1// src/locales/en.json
2{
3 "common": {
4 "welcome": "Welcome to our app",
5 "login": "Log In",
6 "signup": "Sign Up",
7 "logout": "Log Out"
8 },
9 "home": {
10 "title": "Home Page",
11 "description": "Build amazing things with our platform",
12 "cta": "Get Started"
13 },
14 "errors": {
15 "not_found": "Page not found",
16 "generic": "Something went wrong. Please try again."
17 }
18}
19
20// src/locales/es.json
21{
22 "common": {
23 "welcome": "Bienvenido a nuestra aplicacion",
24 "login": "Iniciar sesion",
25 "signup": "Registrarse",
26 "logout": "Cerrar sesion"
27 },
28 "home": {
29 "title": "Pagina principal",
30 "description": "Crea cosas increibles con nuestra plataforma",
31 "cta": "Comenzar"
32 },
33 "errors": {
34 "not_found": "Pagina no encontrada",
35 "generic": "Algo salio mal. Intentalo de nuevo."
36 }
37}

Expected result: You have translation files for each supported language with matching keys and translated values.

3

Configure i18next in your React app

Create an i18n configuration file that initializes the library, loads your translation files, and sets the default language. Import this file at the top level of your app (usually in main.jsx or App.jsx) so translations are available everywhere. The browser language detector automatically selects the user's preferred language based on their browser settings, falling back to your default language if their language is not supported.

typescript
1// src/i18n.js
2import i18n from 'i18next';
3import { initReactI18next } from 'react-i18next';
4import LanguageDetector from 'i18next-browser-languagedetector';
5import en from './locales/en.json';
6import es from './locales/es.json';
7
8i18n
9 .use(LanguageDetector)
10 .use(initReactI18next)
11 .init({
12 resources: {
13 en: { translation: en },
14 es: { translation: es }
15 },
16 fallbackLng: 'en',
17 interpolation: {
18 escapeValue: false // React already escapes
19 },
20 detection: {
21 order: ['localStorage', 'navigator'],
22 caches: ['localStorage']
23 }
24 });
25
26export default i18n;

Expected result: i18next initializes with your translations and auto-detects the user's language. The configuration persists the selected language in localStorage.

4

Use translations in React components

Use the useTranslation hook from react-i18next to access translations in any component. The hook returns a t function that takes a translation key and returns the translated string for the current language. Wrap your app with the I18nextProvider (automatically done by initReactI18next) and replace all hardcoded strings with t() calls. This makes every string in your UI translatable.

typescript
1// src/components/HomePage.jsx
2import { useTranslation } from 'react-i18next';
3
4export default function HomePage() {
5 const { t } = useTranslation();
6
7 return (
8 <div>
9 <h1>{t('home.title')}</h1>
10 <p>{t('home.description')}</p>
11 <button>{t('home.cta')}</button>
12 </div>
13 );
14}

Expected result: The component displays text in the current language. Switching languages updates all t() calls automatically without a page reload.

5

Build a language switcher component

Create a dropdown or button group that lets users switch between languages. Use i18next's changeLanguage method to update the active language. When the language changes, all components using the useTranslation hook re-render with the new translations automatically. Store the selection in localStorage so it persists across page reloads. Place the language switcher in your header or navigation bar for easy access.

typescript
1// src/components/LanguageSwitcher.jsx
2import { useTranslation } from 'react-i18next';
3
4const languages = [
5 { code: 'en', label: 'English' },
6 { code: 'es', label: 'Espanol' }
7];
8
9export default function LanguageSwitcher() {
10 const { i18n } = useTranslation();
11
12 return (
13 <select
14 value={i18n.language}
15 onChange={(e) => i18n.changeLanguage(e.target.value)}
16 style={{ padding: '4px 8px', borderRadius: '4px' }}
17 >
18 {languages.map((lang) => (
19 <option key={lang.code} value={lang.code}>
20 {lang.label}
21 </option>
22 ))}
23 </select>
24 );
25}

Expected result: A dropdown appears in your UI. Selecting a language instantly updates all text on the page. The selection persists in localStorage across reloads.

6

Set up Flask-Babel for Python backends (optional)

If your Replit project uses Flask for the backend, Flask-Babel handles server-side internationalization including date/number formatting and template translations. Configure the supported languages and default locale, then use the gettext function in Jinja2 templates or Flask route handlers to translate strings. Flask-Babel also supports timezone-aware date formatting, which is useful for international users.

typescript
1# app.py
2from flask import Flask, request, render_template
3from flask_babel import Babel, gettext as _
4
5app = Flask(__name__)
6app.config['BABEL_DEFAULT_LOCALE'] = 'en'
7app.config['BABEL_SUPPORTED_LOCALES'] = ['en', 'es', 'fr']
8
9def get_locale():
10 return request.accept_languages.best_match(
11 app.config['BABEL_SUPPORTED_LOCALES']
12 )
13
14babel = Babel(app, locale_selector=get_locale)
15
16@app.route('/')
17def home():
18 return render_template('index.html',
19 title=_('Welcome to our app'),
20 description=_('Build amazing things')
21 )

Expected result: Flask automatically selects the best language based on the user's browser preferences and serves translated content.

Complete working example

src/i18n.js
1/**
2 * i18n configuration for a React app on Replit.
3 * Import this file in main.jsx before rendering the app.
4 *
5 * Usage: import './i18n';
6 * In components: const { t } = useTranslation();
7 */
8import i18n from 'i18next';
9import { initReactI18next } from 'react-i18next';
10import LanguageDetector from 'i18next-browser-languagedetector';
11
12// Import all locale files
13import en from './locales/en.json';
14import es from './locales/es.json';
15
16i18n
17 // Detect user language from browser/localStorage
18 .use(LanguageDetector)
19 // Connect to React
20 .use(initReactI18next)
21 .init({
22 resources: {
23 en: { translation: en },
24 es: { translation: es }
25 },
26 // Default language if detection fails
27 fallbackLng: 'en',
28 // Allow nested keys: t('common.login')
29 keySeparator: '.',
30 interpolation: {
31 // React handles XSS protection
32 escapeValue: false
33 },
34 detection: {
35 // Check localStorage first, then browser language
36 order: ['localStorage', 'navigator', 'htmlTag'],
37 // Save selection to localStorage
38 caches: ['localStorage'],
39 lookupLocalStorage: 'i18nextLng'
40 },
41 // Do not load translations lazily
42 partialBundledLanguages: false
43 });
44
45export default i18n;

Common mistakes when supporting multiple languages in Replit apps

Why it's a problem: Forgetting to import the i18n config file in main.jsx, causing useTranslation to return raw keys instead of translations

How to avoid: Add import './i18n'; at the top of main.jsx or index.jsx, before the React root render call.

Why it's a problem: Using different key structures in translation files (e.g., 'login' in English but 'common.login' in Spanish)

How to avoid: All translation files must use identical key structures. Copy the English file as a template for new languages and only change the values.

Why it's a problem: Hardcoding strings in some components while using t() in others, creating a partially translated app

How to avoid: Audit all components and replace every user-facing string with a t() call. Use ESLint plugins like eslint-plugin-i18next to catch missed strings.

Why it's a problem: Not handling text expansion — German and Spanish text can be 30-40% longer than English, breaking layouts

How to avoid: Test your UI in all supported languages. Use flexible CSS (flexbox, grid) that accommodates varying text lengths without overflow.

Best practices

  • Use descriptive, nested translation keys like 'home.hero.title' instead of generic keys like 'text1' for maintainability
  • Always set a fallbackLng so missing translations show the default language instead of raw keys
  • Store the user's language preference in localStorage so it persists across sessions and page reloads
  • Keep all translation files in a dedicated locales/ directory with one file per language for easy management
  • Start with a small number of languages (2-3) and add more once the i18n infrastructure is solid
  • Use the browser's Accept-Language header as the initial language guess, but always let users override it manually
  • Test your app in each supported language to catch layout issues — some languages produce much longer text than English
  • Extract all hardcoded strings at once rather than incrementally to avoid a half-translated app

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a React app on Replit and I want to add support for [languages]. The app currently has hardcoded English strings. Help me set up react-i18next, create translation files, and build a language switcher component.

Replit Prompt

Add multi-language support to this React app. Install react-i18next, create translation files for English and Spanish in a src/locales/ directory, replace all hardcoded strings with t() translation calls, and add a language switcher component in the header. Make sure the selected language persists in localStorage.

Frequently asked questions

No. Replit is a development platform and does not provide i18n features. You implement internationalization using standard libraries like react-i18next or Flask-Babel, just as you would in any web project.

There is no limit from Replit. The constraint is your translation files' total size, which counts against your storage quota. Each language file is typically 1-20 KB, so even 50 languages would use minimal storage.

Yes. You can ask Agent to create translation files based on your English source. However, AI-generated translations may not be perfect — have a native speaker review them before publishing.

Add a dir attribute to your HTML element based on the current language. In React: document.documentElement.dir = isRTL ? 'rtl' : 'ltr'. You may also need Tailwind CSS RTL plugins or CSS logical properties.

For most Replit apps, store translations in the frontend as JSON files. This avoids API calls for every translation. For very large translation sets or dynamic content, consider loading translations from a database or API.

Yes. RapidDev can help implement i18n architecture, set up translation workflows, configure RTL support, and integrate with translation management platforms for larger multi-language projects.

Use interpolation: in your JSON file, write "welcome": "Hello, {{name}}!". In your component, call t('welcome', { name: user.name }). i18next replaces {{name}} with the actual value.

No. react-i18next uses React's reactivity system. When you call i18n.changeLanguage(), all components using useTranslation() re-render with the new language instantly without a page reload.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.