On this page
Overview
Laravel Localizer Vue is the Vue 3 frontend for Laravel Localizer. The Laravel package turns your language files into generated TypeScript; this package reads them in components through a useLocalizer() composable and ships a Vite plugin that re-runs the generator whenever a language file changes.
Locale, text direction and the list of available locales come from Inertia’s shared locale prop and are exposed as computed refs, so templates update when the server switches language. If you build with React instead, use Laravel Localizer React. The package is MIT licensed and maintained by the DevWizard core team.
Features
useLocalizer()composable returning__,trans,lang,has,choice,locale,dir,availableLocales,translationsandgetLocales.locale,dir,availableLocalesandtranslationsareComputedRefvalues.- Placeholder replacement in both
:nameand{name}styles. - Optional fallback text for missing keys.
- Vite plugin, exported from the
/viteentry, that regenerates the TypeScript files on build start and when language files change. - Exported types:
Replacements,LocaleData,PagePropsandUseLocalizerReturn. - ESM build with
sideEffectsdisabled.
Requirements
- Vue 3.
@inertiajs/vue31, 2 or 3.- Vite 5, 6, 7 or 8 for the plugin.
- The Laravel Localizer backend package, with the middleware registered so the
localeprop is shared.
Installation
pnpm add @devwizard/laravel-localizer-vueOther package managers:
npm install @devwizard/laravel-localizer-vue
yarn add @devwizard/laravel-localizer-vueInstall the backend first if you have not already:
composer require devwizardhq/laravel-localizer
php artisan localizer:install --framework=vueConfiguration
Generate the TypeScript files once, then wire up the Vite plugin and the global translations object.
php artisan localizer:generate --allAdd the plugin to vite.config.ts:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import laravel from 'laravel-vite-plugin';
import { laravelLocalizer } from '@devwizard/laravel-localizer-vue/vite';
export default defineConfig({
plugins: [
laravel({ input: ['resources/js/app.ts'], refresh: true }),
vue(),
laravelLocalizer(),
],
});The plugin options, all optional:
| Option | Default | Description |
|---|---|---|
patterns |
['lang/**', 'resources/lang/**'] |
Globs, relative to the project root, that trigger regeneration |
command |
'php artisan localizer:generate --all' |
Shell command to run |
debug |
false |
Log extra messages about detected changes |
The composable reads translations from window.localizer, so set it in your entry file before mounting the app:
import * as translations from './lang';
window.localizer = { translations };Optionally declare the global type:
declare global {
interface Window {
localizer: {
translations: typeof translations;
};
}
}Usage
Call the composable in script setup:
<script setup lang="ts">
import { useLocalizer } from '@devwizard/laravel-localizer-vue';
const { __, dir } = useLocalizer();
</script>
<template>
<section :dir="dir">
<h1>{{ __('welcome') }}</h1>
<p>{{ __('greeting', { name: 'Sam' }) }}</p>
</section>
</template>Replacements work with :name and {name} placeholders in the translation string. A missing key returns the fallback you pass as the third argument, or the key itself:
__('might.not.exist', {}, 'Default text');Use has() to test for a key and choice() to pass a count into the string:
const { has, choice } = useLocalizer();
has('welcome');
choice('apples', 5, { unit: 'kg' });API Reference
useLocalizer()
| Member | Type | Description |
|---|---|---|
__, trans, lang |
(key, replacements?, fallback?) => string |
Translate a key; the three are the same function |
has |
(key) => boolean |
Whether the key exists for the current locale |
choice |
(key, count, replacements?) => string |
Translate and substitute count |
locale |
ComputedRef<string> |
Current locale, 'en' if the prop is missing |
dir |
ComputedRef of 'ltr' or 'rtl' |
Text direction, 'ltr' if missing |
availableLocales |
ComputedRef of label, flag and dir |
Locales from the shared prop |
translations |
ComputedRef<Record<string, string>> |
All strings for the current locale |
getLocales |
() => string[] |
Locale codes |
choice() adds count to the replacements and translates the key. It does not split pipe-separated plural forms, so the string itself must contain the wording you want, for example You have :count apples.
Vite plugin
laravelLocalizer(options) from @devwizard/laravel-localizer-vue/vite, also its default export. It runs command on build start and on hot updates of files matching patterns. The command runs asynchronously and errors are reported through Vite.
Examples
A locale switcher built from the shared props. It assumes the backend middleware reads the locale query parameter:
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { useLocalizer } from '@devwizard/laravel-localizer-vue';
const { locale, availableLocales } = useLocalizer();
const change = (code: string) => router.get(window.location.pathname, { locale: code });
</script>
<template>
<select :value="locale" @change="change(($event.target as HTMLSelectElement).value)">
<option v-for="(meta, code) in availableLocales" :key="code" :value="code">
{{ meta.flag }} {{ meta.label }}
</option>
</select>
</template>Handle a right-to-left layout by binding dir:
<main :dir="dir"><slot /></main>Point the plugin at a custom command, for example when PHP runs in a container:
laravelLocalizer({
command: 'docker compose exec app php artisan localizer:generate --all',
debug: true,
});FAQ & Troubleshooting
The console warns that translations are not initialized. Set window.localizer = { translations } in your entry file before mounting, using the index generated by localizer:generate.
Keys show instead of text. Check that the locale prop is shared (the Laravel middleware must be registered) and that a generated file exists for the current locale.
Do I need .value on locale and dir? In script code yes, because they are computed refs. In templates they unwrap automatically.
Does choice() handle singular and plural forms? No. It only substitutes count. Provide a string such as :count apples or choose the wording in your component.
Translations do not update during development. Confirm the plugin is in vite.config.ts and that php is on the path where Vite runs. Turn on debug to see the change detection messages.
Changelog & Support
Release history is in the CHANGELOG and on the GitHub releases page. Open bugs and feature requests in GitHub issues. Source: DevWizardHQ/laravel-localizer-vue. Using React instead? See Laravel Localizer React. For help with multilingual products, the DevWizard team takes project contracts and monthly retainers through the contact page.