# How the Vue.js Quiz App in Microsoft's AI-For-Beginners Handles Translations with vue-i18n

> Learn how the Vue.js quiz app in Microsoft's AI-For-Beginners uses vue-i18n for translations. Discover its approach to loading language bundles and accessing locales for multilingual content.

- Repository: [Microsoft/AI-For-Beginners](https://github.com/microsoft/AI-For-Beginners)
- Tags: how-to-guide
- Published: 2026-08-18

---

**The quiz application uses vue-i18n to initialize a global i18n instance with locale fallback settings, loads language-specific JSON bundles through a centralized translations module, and lets components access the active locale via `this.$root.$i18n.locale` to render multilingual quiz content.**

The Microsoft **AI-For-Beginners** repository includes a Vue.js-based quiz application that demonstrates practical internationalization patterns. This guide examines how the app leverages **vue-i18n** to support multiple languages through a clean, maintainable architecture.

## vue-i18n Initialization in src/main.js

The translation system boots in [`src/main.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/main.js), where the plugin is registered and configured.

```javascript
// src/main.js – Vue-i18n setup
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import router from './router';
import App from './App.vue';

Vue.use(VueI18n);

const i18n = new VueI18n({
  locale: 'en',          // default language
  fallbackLocale: 'en', // fallback if translation missing
});

new Vue({
  i18n,
  router,
  render: h => h(App),
}).$mount('#app');

```

The `VueI18n` instance is created with `locale: 'en'` and `fallbackLocale: 'en'` to ensure graceful degradation. Passing this instance to the root Vue constructor makes **`$i18n`** available throughout the component tree.

## Translation Bundle Organization

### Centralized Message Loading

All translations are aggregated in [`src/assets/translations/index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/assets/translations/index.js). This file imports language-specific modules and exports a `messages` object mapping locale codes to their data.

```javascript
// src/assets/translations/index.js – bundle aggregation
import englishQuizzes from './en';
import spanishQuizzes from './es';

export default {
  en: englishQuizzes,
  es: spanishQuizzes,
};

```

### Per-Language Module Structure

Each locale folder contains an [`index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/index.js) that imports per-lesson JSON files. The English module at [`src/assets/translations/en/index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/assets/translations/en/index.js) demonstrates this pattern:

```javascript
// Imports all lesson JSON files and builds a flat quiz object
import lesson1 from './lesson-1.json';
import lesson2 from './lesson-2.json';
// ... additional lesson imports

export default {
  quiz: {
    1: lesson1,
    2: lesson2,
    // ...
  }
};

```

The JSON files ([`lesson-1.json`](https://github.com/microsoft/AI-For-Beginners/blob/main/lesson-1.json), [`lesson-2.json`](https://github.com/microsoft/AI-For-Beginners/blob/main/lesson-2.json), etc.) store quiz titles, questions, and answer options. This structure separates **content data** from **UI translations**, a common pattern in educational applications.

## Component-Level Locale Access in Quiz.vue

The [`Quiz.vue`](https://github.com/microsoft/AI-For-Beginners/blob/main/Quiz.vue) component consumes these bundles through computed properties tied to **vue-i18n**'s reactive locale state.

```javascript
// src/components/Quiz.vue – consuming translations
import messages from '@/assets/translations';

export default {
  computed: {
    // Expose the full message map to the template
    questions() {
      return messages;
    },
    // Read the active locale from the root i18n instance
    currLocale() {
      return this.$root.$i18n.locale;
    },
  },
  // Template accesses questions[currLocale] to retrieve correct language data
};

```

The component reads `this.$root.$i18n.locale` rather than `this.$i18n.locale`, ensuring it tracks the global locale state regardless of nested component depth.

## Dynamic Locale Selection

The [`Quiz.vue`](https://github.com/microsoft/AI-For-Beginners/blob/main/Quiz.vue) component handles runtime language switching through the `created()` lifecycle hook:

```javascript
// From src/components/Quiz.vue lines 81-86
created() {
  if (this.$route.query.loc) {
    this.locale = this.$route.query.loc;
  } else {
    this.locale = 'en';
  }
}

```

The `loc` query parameter (e.g., `/quiz/1?loc=es`) allows URL-driven language selection. While `this.locale` is assigned here, the reactive system ultimately responds to changes in `this.$root.$i18n.locale`, enabling external language switchers to update the UI.

## Key Implementation Patterns

- **Global instance injection**: vue-i18n is installed once and passed to the root Vue instance, avoiding prop drilling
- **Static bundle imports**: Translations are bundled at build time rather than fetched dynamically, suitable for a fixed-content quiz app
- **Computed property reactivity**: `currLocale` re-evaluates when `$i18n.locale` changes, triggering template updates
- **Query parameter initialization**: Routes accept `?loc=` to preselect language on direct navigation

## Summary

- **vue-i18n initialization** happens in [`src/main.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/main.js) with default and fallback locales set to `'en'`
- **Translation bundles** are centralized in [`src/assets/translations/index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/assets/translations/index.js), aggregating per-language modules
- **JSON content files** for each lesson are imported and exposed through locale-specific index files
- **Quiz.vue** accesses translations via computed properties tied to `this.$root.$i18n.locale`
- **URL parameters** allow initial locale selection through the `loc` query string

## Frequently Asked Questions

### How does the quiz app switch languages without page reload?

The app relies on vue-i18n's reactive integration. When `this.$root.$i18n.locale` changes, computed properties like `currLocale` re-evaluate automatically. The template then indexes into `questions[currLocale]`, causing Vue's reactivity system to update the rendered quiz content without navigation.

### Why does Quiz.vue use `this.$root.$i18n.locale` instead of `this.$i18n.locale`?

This ensures the component reads the global locale state from the root instance. In nested component trees, `$i18n` might reference a localized scope; `$root.$i18n` guarantees access to the singleton instance created in [`src/main.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/main.js).

### Can new languages be added without modifying component code?

Yes. Adding a new language requires: (1) creating a new folder under `src/assets/translations/` with lesson JSON files and an [`index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/index.js) exporter, (2) importing it in [`src/assets/translations/index.js`](https://github.com/microsoft/AI-For-Beginners/blob/main/src/assets/translations/index.js), and (3) ensuring the locale code matches what vue-i18n expects. No changes to [`Quiz.vue`](https://github.com/microsoft/AI-For-Beginners/blob/main/Quiz.vue) or other components are necessary.

### Does the app support runtime translation loading?

No. The current implementation uses static ES6 imports, bundling all translations at build time. This keeps the application simple and offline-capable but increases initial bundle size. For larger applications, vue-i18n's **lazy loading** with dynamic imports would be recommended.