Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

angelorigo's avatar

Internationalization with separate json files for each request

Hi,

I setup a project with Laravel 12 using InertiaJs and Vuejs and Internationalization .

How can i load only the required strings at each request ?

Instead of all the json strings at each request ?

I See the resolve function reach the lang directory at : resources/js/app.ts

createInertiaApp({ title: (title) => ${title} - ${appName}, resolve: (name) => resolvePageComponent(./pages/${name}.vue, import.meta.glob<DefineComponent>('./pages/**/.vue')), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ZiggyVue) .use(i18nVue, { resolve: async lang => { const langs = import.meta.glob('../../lang/.json'); return await langs../../lang/${lang}.json; }

Wich files must to be edited and what the necessary modifications to load only the translation strings used at each individual request ?

0 likes
1 reply
LaryAI's avatar
Level 58

To load only the required translation strings per request in a Laravel + Inertia.js + Vue.js setup, you need to:

  1. Split your translation files into smaller JSON files, ideally by page or component.
  2. Dynamically import only the necessary translation files when a page/component is loaded.
  3. Configure your i18n setup to support this dynamic loading.

Here’s a step-by-step solution:


1. Organize Your Translation Files

Instead of a single en.json, split your translations by page/component:

resources/lang/en/
  ├── auth.json
  ├── dashboard.json
  └── profile.json
resources/lang/fr/
  ├── auth.json
  ├── dashboard.json
  └── profile.json

2. Dynamic Import in Your i18n Setup

In your resources/js/app.ts (or main.ts), configure i18nVue to resolve translation files dynamically based on the current page/component.

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import { i18nVue } from 'laravel-vue-i18n'

createInertiaApp({
  // ...other options
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .use(i18nVue, {
        resolve: async lang => {
          // Only load the base translation file (optional)
          const base = await import(`../../lang/${lang}/base.json`).catch(() => ({}))

          // Dynamically load the translation file based on the current page/component
          // For example, if you have a page named "Dashboard"
          const page = props.initialPage.component.toLowerCase() // e.g., 'dashboard'
          const pageTranslations = await import(`../../lang/${lang}/${page}.json`).catch(() => ({}))

          // Merge and return
          return { ...base, ...pageTranslations }
        }
      })
      .mount(el)
  }
})

3. Pass the Page Name to the Resolver

If you need more control, you can pass the page/component name to the resolver. For example, you can set a global property or use Inertia's props to indicate which translation file to load.


4. Use Translations in Vue Components

Now, in your Vue components, use the $t function as usual:

<template>
  <div>{{ $t('welcome') }}</div>
</template>

5. Optional: Lazy Load Translations Per Component

If you want to load translations per component (not just per page), you can use Vue's defineAsyncComponent or similar strategies to import translations only when a component is loaded.


Summary

  • Split translation files by page/component.
  • Dynamically import only the necessary translation file in the i18n resolver.
  • Merge with a base translation file if needed.
  • Use the translations as usual in your Vue components.

This approach ensures only the required translation strings are loaded for each request, improving performance and reducing payload size.

Let me know if you need a more specific code example for your exact folder structure or setup!

Please or to participate in this conversation.