Hone logo
Hone
Problems

Vue i18n Plugin Implementation

This challenge asks you to implement a basic i18n (internationalization) plugin for Vue.js using TypeScript. A well-implemented i18n plugin allows your Vue application to display content in different languages, enhancing its usability for a global audience. This plugin will handle loading translations and providing a method to translate text within your components.

Problem Description

You need to create a Vue plugin named i18nPlugin that provides internationalization functionality. The plugin should:

  1. Accept a translation object: The plugin should be initialized with a translation object. This object will be a JavaScript object where keys are language codes (e.g., 'en', 'fr', 'es') and values are objects containing translations for different keys. For example: { en: { 'greeting': 'Hello', 'goodbye': 'Goodbye' }, fr: { 'greeting': 'Bonjour', 'goodbye': 'Au revoir' } }.
  2. Set a default language: The plugin should accept a defaultLanguage parameter during initialization (e.g., 'en'). This language will be used if no language is explicitly specified.
  3. Provide a t method: The plugin should inject a t method into all Vue components. This method will accept a key (e.g., 'greeting') and optionally a language code. It should return the translated string for the given key and language. If the language code is not provided, it should use the current active language. If the key is not found in the specified language, it should return the key itself (as a fallback).
  4. Provide a currentLanguage property: The plugin should expose a currentLanguage property that can be accessed globally (e.g., through this.$i18n.currentLanguage).
  5. Provide a setLanguage method: The plugin should expose a setLanguage method that allows changing the active language. This method should accept a language code as an argument and update the currentLanguage property.

Expected Behavior:

  • When a component calls this.$i18n.t('greeting'), it should return the translated string for the 'greeting' key in the current language.
  • When a component calls this.$i18n.t('greeting', 'fr'), it should return the translated string for the 'greeting' key in French.
  • If a key is not found in the specified language, the t method should return the key itself.
  • this.$i18n.currentLanguage should reflect the currently active language.
  • Calling this.$i18n.setLanguage('es') should change the current language to Spanish.

Examples

Example 1:

Input:
translations = {
  en: {
    'greeting': 'Hello',
    'goodbye': 'Goodbye'
  },
  fr: {
    'greeting': 'Bonjour',
    'goodbye': 'Au revoir'
  }
};
defaultLanguage = 'en';

Component Code:
<template>
  <div>
    <p>{{ $i18n.t('greeting') }}</p>
    <p>{{ $i18n.t('goodbye', 'fr') }}</p>
  </div>
</template>

Output:

<div>
  <p>Hello</p>
  <p>Au revoir</p>
</div>

Explanation: The first t call uses the default language ('en'), so it returns 'Hello'. The second t call explicitly specifies 'fr', so it returns 'Au revoir'.

Example 2:

Input:
translations = {
  en: {
    'greeting': 'Hello'
  }
};
defaultLanguage = 'en';

Component Code:
<template>
  <div>
    <p>{{ $i18n.t('farewell') }}</p>
  </div>
</template>

Output:

<div>
  <p>farewell</p>
</div>

Explanation: The key 'farewell' is not found in the English translations, so the t method returns the key itself.

Example 3: (Language Switching)

Input:
translations = {
  en: {
    'greeting': 'Hello'
  },
  fr: {
    'greeting': 'Bonjour'
  }
};
defaultLanguage = 'en';

Component Code:
<template>
  <div>
    <p>{{ $i18n.t('greeting') }}</p>
    <button @click="$i18n.setLanguage('fr')">Switch to French</button>
  </div>
</template>

Output (after clicking the button):

<div>
  <p>Bonjour</p>
</div>

Explanation: Initially, the greeting is 'Hello' (default language). After clicking the button, the language is switched to French, and the greeting updates to 'Bonjour'.

Constraints

  • The plugin must be implemented using TypeScript.
  • The translation object should be a plain JavaScript object.
  • The plugin should be compatible with Vue 3.
  • The t method should be performant, even with large translation objects. Avoid unnecessary iterations.
  • The plugin should not modify the original translation object.

Notes

  • Consider using Vue's provide and inject API to make the t method available to all components.
  • Think about how to handle missing translations gracefully. Returning the key itself is a simple fallback, but you could also consider logging an error or displaying a placeholder.
  • This is a simplified i18n plugin. Real-world i18n plugins often include features like pluralization, date formatting, and number formatting. This challenge focuses on the core translation functionality.
  • Focus on clean, readable, and well-documented code.
Loading editor...
typescript