Hone logo
Hone
Problems

Vue i18n Plugin Implementation

Internationalization (i18n) is crucial for making web applications accessible to a global audience. This challenge asks you to build a foundational i18n plugin for Vue 3 using TypeScript. The plugin should allow developers to easily manage translations, switch languages, and display translated text within their Vue applications.

Problem Description

You need to create a Vue 3 plugin that provides i18n capabilities. The plugin should:

  1. Load Translations: Accept a configuration object containing translations for different locales.
  2. Set Locale: Allow the application to set the current active locale.
  3. Translate Text: Provide a function to retrieve translated strings based on a given key and the current locale.
  4. React to Locale Changes: When the locale changes, any displayed translations should update automatically.

Key Requirements:

  • The plugin must be installable via app.use().
  • Translations should be structured as an object where keys represent locale codes (e.g., 'en', 'fr') and values are objects containing translation key-value pairs.
  • A global method or property should be exposed to allow setting the current locale.
  • A global method or property should be exposed to retrieve translated strings using a key.
  • The translation system should be reactive, meaning that changes to the current locale should trigger re-renders of components displaying translated text.
  • The solution must be implemented in TypeScript.

Expected Behavior:

When the plugin is installed and configured, a Vue component should be able to:

  • Display translated text using a provided directive or method (e.g., {{ $t('greeting') }} or v-t="'greeting'").
  • Change the application's language dynamically (e.g., by calling a $setLocale('fr') method).

Edge Cases:

  • Handling missing translation keys gracefully (e.g., returning the key itself or a default string).
  • Handling cases where a locale is not found in the provided translations.

Examples

Example 1: Basic Translation

Let's assume the plugin is configured with English and French translations.

Plugin Configuration:

const messages = {
  en: {
    greeting: 'Hello!',
    farewell: 'Goodbye!',
  },
  fr: {
    greeting: 'Bonjour!',
    farewell: 'Au revoir!',
  },
};

Vue Component (using a hypothetical $t method):

<template>
  <div>
    <h1>{{ $t('greeting') }}</h1>
    <p>{{ $t('farewell') }}</p>
  </div>
</template>

Input:

  • Plugin is installed with messages above.
  • Current locale is set to 'en'.

Output (rendered in template):

<div>
  <h1>Hello!</h1>
  <p>Goodbye!</p>
</div>

Explanation:

The $t method looks up the key greeting in the en locale and returns 'Hello!'. Similarly, farewell returns 'Goodbye!'.

Example 2: Switching Locales

Input:

  • Same messages configuration as Example 1.
  • Current locale is initially set to 'en'.
  • The application then calls a method to set the locale to 'fr'.

Output (after switching locale to 'fr'):

The same Vue component from Example 1 will now render:

<div>
  <h1>Bonjour!</h1>
  <p>Au revoir!</p>
</div>

Explanation:

When the locale is switched to 'fr', the $t method now looks up keys in the fr translation object, dynamically updating the displayed text.

Example 3: Missing Translation Key

Input:

  • Plugin is configured with the messages from Example 1.
  • Current locale is set to 'en'.
  • A component tries to translate a non-existent key: {{ $t('welcome') }}.

Output:

The component will render the key itself as a fallback.

<div>
  <h1>welcome</h1>
</div>

Explanation:

Since 'welcome' does not exist in the en locale, the plugin should return the key as a default.

Constraints

  • The solution must be compatible with Vue 3.
  • All code must be written in TypeScript.
  • The plugin should not introduce significant performance overhead for typical translation lookups.
  • The plugin should not rely on external i18n libraries. You are building the core logic.

Notes

  • Consider how you will make the current locale and translations accessible to all components in your Vue application. Vue's provide/inject mechanism or a global state management approach might be relevant.
  • Think about how to expose the translation function and locale switching mechanism to components. A common pattern is to attach them to the Vue application instance (e.g., app.config.globalProperties).
  • For reactivity, you'll likely need to use Vue's reactive primitives (like ref or reactive) to manage the current locale.
  • You might want to implement a simple directive (v-t) in addition to a global method for a more idiomatic Vue experience.
Loading editor...
typescript