Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Implementing Multi-Framework Internationalization in React, Vue, and Element UI

Notes 1

Language Configuration Fundamentals

The HTML lang Attribute

Setting the correct language code in the <html> tag is essential for accessibility, SEO, and browser-specific features like automatic translation prompts.

<html lang="en"> <!-- English -->
<html lang="zh-CN"> <!-- Simplified Chinese -->
<html lang="es"> <!-- Spanish -->

Automated Language Detection

In production environments, logic often dictates falling back to a default language (usually English) if the detected environment is not the primary target (e.g., Chinese).

const detectUserLocale = (): string => {
  const metadata = (window as any).appConfig?.localeInfo;
  const currentLang = metadata ? metadata.language : 'en';
  return currentLang === 'zh' ? 'zh' : 'en';
};

const isMandarin = detectUserLocale() === 'zh';

Core Concepts of i18n Functions

Simple Translation with t()

The t function retrieves strings from resource files based on keys. It supports variable interpolation to inject dynamic data.

// resource.json
{
  "greeting": "Welcome back, {{name}}!"
}

// Usage
t('greeting', { name: 'Alex' }); // Output: Welcome back, Alex!

Pluralization with tc()

Modern i18n libraries use pluralization logic to handle singular and plural forms based on a numeric value.

// Translation keys
{
  "task_count": "No tasks remaining | One task left | {{count}} tasks pending"
}

// Logic
$tc('task_count', 0); // "No tasks remaining"
$tc('task_count', 1); // "One task left"
$tc('task_count', 5, { count: 5 }); // "5 tasks pending"

Contextual Variants

Sometimes the same word has different translations based on its usage (e.g., as a noun vs. a verb).

t('action.close', { context: 'verb' }); // "Close the window"
t('action.close', { context: 'adj' }); // "The store is close"

React Integration with react-i18next

React uses a hook-based approach to provide translation functions within functional components. Resources are often split into namespaces (files) to improve performance.

import React from 'react';
import { useTranslation } from 'react-i18next';

const DashboardHeader = ({ user, activeJobs }: { user: string, activeJobs: number }) => {
  const { t } = useTranslation(['dashboard', 'common']);

  return (
    <header>
      <h1>{t('dashboard:welcome', { username: user })}</h1>
      <p>{t('dashboard:status', { count: activeJobs })}</p>
      <button>{t('common:logout', { defaultValue: 'Exit' })}</button>
    </header>
  );
};

export default DashboardHeader;

Vue 3 Integration with vue-i18n

In Vue, the i18n instance is typically injected into the global prototype, allowing access via this.$t in Options API or through a composable in Composition API.

Dynamic Resource Loading

Using Webpack's require.context or Vite's import.meta.glob, you can automate the registration of translation files.

import { createI18n } from 'vue-i18n';

const loadLocaleMessages = () => {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i);
  const messages: Record<string, any> = {};
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i);
    if (matched && matched.length > 1) {
      const locale = matched[1];
      messages[locale] = locales(key).default;
    }
  });
  return messages;
};

export const i18n = createI18n({
  legacy: false,
  locale: localStorage.getItem('user_lang') || 'en',
  fallbackLocale: 'en',
  messages: loadLocaleMessages(),
});

Element UI Component Compatibility

UI libraries like Element UI (or Element Plus) contain internal strings (e.g., date picker labels) that must be synchronized with the application's locale.

Global Configuration

To ensure library components reflect the selected language, merge the library's locale with your custom translations.

import ElementUI from 'element-ui';
import enLocale from 'element-ui/lib/locale/lang/en';
import zhLocale from 'element-ui/lib/locale/lang/zh-CN';

const currentLang = detectUserLocale();
const elementLocale = currentLang === 'zh' ? zhLocale : enLocale;

Vue.use(ElementUI, { locale: elementLocale });

Manual Integration for Specific Overrides

If you need to modify specific strings within the UI library without changing the entire locale file, you can extend the object manually.

const customEn = {
  ...enLocale,
  el: {
    ...enLocale.el,
    datepicker: {
      ...enLocale.el.datepicker,
      today: 'Current Day' // Overriding default 'Today'
    }
  }
};

Performance and Delivery Optimization

Static Data Efficiency

For large datasets (like feature lists or help documentation), returning a language-specific object directly from a TypeScript utility is more performant than parsing deep JSON trees.

export const getFeatureSet = (lang: string) => {
  const content = {
    en: [
      { id: 1, label: 'Analytics', desc: 'Real-time data tracking' },
      { id: 2, label: 'Security', desc: 'End-to-end encryption' }
    ],
    zh: [
      { id: 1, label: '数据分析', desc: '实时数据追踪' },
      { id: 2, label: '安全防护', desc: '端到端加密' }
    ]
  };
  return content[lang] || content['en'];
};

CDN for Global Assets

Offloading locale files to a Content Delivery Network (CDN) provides several advantages:

  1. Reduced Latency: Users download assets from the nearest geographical server.
  2. Browser Caching: Common libraries hosted on CDNs are often already cached in the user's browser.
  3. Independent Scaling: Language updates can be deployed by refreshing the CDN cache without a full aplication rebuild.
  4. Reliability: Multi-node redundancy ensures translation files remain available even if the main origin server experiences downtime.

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.