DEV Community

catatsumuri
catatsumuri

Posted on

Localized Out of the Box with `laravel new` — i18n for Laravel Starter Kits (React/Vue/Svelte)

Laravel's official Starter Kits currently support internationalization (i18n) only in the Livewire version. The Inertia-based kits (React / Vue / Svelte) still have all UI text hardcoded in English. Although support is being discussed upstream (laravel/maestro#168), I created and published localized forks as a temporary solution until official support arrives.

These forks differ from the official kits in four ways:

  • Japanese is available immediatelyja language resources are included. Just change one line in .env
  • All UI strings go through __() — hardcoded English text has been replaced with translatable strings
  • Adding languages is easy — just add a JSON file and run a command (see the French example below)
  • Locale is stored in the session — the selected language persists after page reloads

Only the equivalent of each repository's main branch is provided. teams and WorkOS variants are not available.

For Those Who Just Want to Try It

composer global require laravel/installer # if not installed
laravel new Your_App --using=https://github.com/catatsumuri/react-starter-kit-i18n
cd Your_App
composer dev
Enter fullscreen mode Exit fullscreen mode

Then change APP_LOCALE in .env to ja and restart the development server. Detailed setup instructions are explained later, but first, here is a demo.

Try the Demo First

A demo in a fully localized Japanese state is available on Laravel Cloud.

Localized login screen

You can log in using the following account. The database is read-only, so feel free to explore.

  • Email: test@example.com
  • Password: password

Actual Setup

Prerequisites

You need the laravel command (Laravel Installer) and npm. If the installer is not installed:

composer global require laravel/installer
Enter fullscreen mode Exit fullscreen mode
% laravel --version
Laravel Installer 5.28.1
Enter fullscreen mode Exit fullscreen mode

(This article does not cover Docker-based setups.)

Specify the Custom Starter Kit with laravel new

Simply pass the repository URL to the --using option of laravel new. The example below uses React, but Vue and Svelte follow the same procedure with different URLs.

# Replace Your_App
laravel new Your_App --using=https://github.com/catatsumuri/react-starter-kit-i18n
Enter fullscreen mode Exit fullscreen mode

The repositories again:

I primarily use the React version. The Vue and Svelte versions use the same mechanism, but there may be rough edges. If you find any issues, I'd appreciate an issue report.

When you run the command, it enters interactive mode and asks several questions. The defaults are generally fine.

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ › ● Pest                                                     │
 │   ○ PHPUnit                                                  │
 └──────────────────────────────────────────────────────────────┘

 ┌ Do you want to install Laravel Boost to improve AI assisted coding? ┐
 │ ● Yes / ○ No                                                        │
 └─────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Next, select authentication features.

 ┌ Which authentication features would you like to enable? ─────┐
 │ › ◼ Email verification                                       │
 │   ◼ Registration                                             │
 │   ◼ Two-factor authentication                                │
 │   ◼ Passkeys                                                 │
 │   ◼ Password confirmation                                    │
 └──────────────────────────────────────────────────────────────┘
  Use space to select, enter to confirm.
Enter fullscreen mode Exit fullscreen mode

If you enable Registration, the application will allow anyone to create an account. Make sure this matches your intended behavior before selecting it.

Finally, you'll be asked whether to run npm. Choosing Yes is usually the safest option.

 ┌ Would you like to run npm install --ignore-scripts and npm run build? ┐
 │ ● Yes / ○ No                                                          │
 └───────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

If you see the following, setup is complete:

 Application ready in [Your_App]. You can start your local development using:

 ➜ cd Your_App
 ➜ composer run dev

 New to Laravel? Check out our documentation. Build something amazing!
Enter fullscreen mode Exit fullscreen mode

Verify Startup

cd Your_App
composer dev
Enter fullscreen mode Exit fullscreen mode

Start the development server and access http://localhost:8000. On first launch, you'll likely encounter a database connection error.

If SQLite is sufficient, run the following in another terminal:

php artisan migrate:fresh --seed --force
Enter fullscreen mode Exit fullscreen mode

Reload the page and the application should be running.

Switch to Japanese

At this point, the application is still in English. However, this fork already deploys Japanese resources into lang/ during installation (adding other languages is explained later).

% tree lang
lang
├── en
│   ├── actions.php
│   ├── auth.php
│   ├── http-statuses.php
│   ├── pagination.php
│   ├── passwords.php
│   └── validation.php
├── en.json
├── ja
│   ├── actions.php
│   ├── auth.php
│   ├── http-statuses.php
│   ├── pagination.php
│   ├── passwords.php
│   └── validation.php
├── ja.json
└── vendor-patches
    ├── locales
    │   └── ja.json
    └── source
        └── react.json
Enter fullscreen mode Exit fullscreen mode

All you need to do is change .env.

#APP_LOCALE=en
APP_LOCALE=ja
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
Enter fullscreen mode Exit fullscreen mode

Restart the development server that was running via composer dev, and the application will switch to Japanese.

Localized login screen

You can log in with the seeded account test@example.com / password.

Logged-in screen

Settings page is also localized


Recommended Workflow for Multilingual Development

To preserve internationalization during development, write UI strings using the __() helper. It can be used directly inside React components (translations are provided via Inertia shared props).

import { lang } from '@erag/lang-sync-inertia/react';
// ...
export default function Login({ status, canResetPassword }: Props) {
    const { __ } = lang();
    // ...
    {__('Fallback Language(English)')}
Enter fullscreen mode Exit fullscreen mode

Actual usage example:

https://github.com/catatsumuri/react-starter-kit-i18n/blob/main/resources/js/pages/auth/login.tsx#L116-L121

If no translation exists for a key, the English fallback locale is displayed, so nothing breaks. For projects that do not require multilingual support, it's perfectly acceptable to continue development directly in your localized language.


Adding Another Language — French Example

Japanese is automatically deployed during installation through a Composer script, but adding other languages is also simple. Translation resources consist of two layers:

  • Base translations (validation messages, authentication errors, etc.) — provided by Laravel Lang for many languages
  • UI strings specific to this fork (such as the 2FA settings screen) — stored in lang/vendor-patches/locales/{locale}.json

To add French, create fr.json based on lang/vendor-patches/locales/ja.json.

cat lang/vendor-patches/locales/fr.json
{
    "Navigation menu": "Menu de navigation",
    "Once your account is deleted, all of its resources and data will also be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "Une fois votre compte supprimé, toutes ses ressources et données seront également supprimées définitivement. Veuillez saisir votre mot de passe pour confirmer la suppression définitive de votre compte.",
    "Please proceed with caution, this cannot be undone.": "Veuillez procéder avec prudence, cette action est irréversible."
}
Enter fullscreen mode Exit fullscreen mode

Reference (an actual implementation exists in the locale-switcher branch):

https://github.com/catatsumuri/react-starter-kit-i18n/blob/feature/locale-switcher/lang/vendor-patches/locales/fr.json

Even if translations are incomplete, missing keys fall back to English. After creating the file, apply the patch and regenerate language files.

composer patch-vendor
php artisan lang:update
Enter fullscreen mode Exit fullscreen mode
% php artisan lang:update

   INFO  Collecting translations...

  LaravelLang\Actions\Plugin ................................. 2.42ms DONE
  LaravelLang\Lang\Plugin ................................... 16.39ms DONE
  LaravelLang\StarterKits\Plugin ............................. 2.52ms DONE

   INFO  Storing changes...

  fr.json ................................................... 10.80ms DONE
  fr/actions.php ............................................. 6.17ms DONE
  fr/auth.php ................................................ 0.29ms DONE
  fr/validation.php ......................................... 14.22ms DONE
  (en / ja are regenerated as well)
Enter fullscreen mode Exit fullscreen mode

This generates lang/fr.json and lang/fr/*.php. Then simply update .env and restart the development server.

#APP_LOCALE=en
#APP_LOCALE=ja
APP_LOCALE=fr
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
Enter fullscreen mode Exit fullscreen mode

Switched to French

Bonus: Locale Switcher (Language Switching UI)

A UI for switching languages directly from the application is also available in the feature/locale-switcher branch.

Locale switcher demo

To install directly from this branch, append #branch-name to the URL.

laravel new Your_App --using=https://github.com/catatsumuri/react-starter-kit-i18n#feature/locale-switcher
Enter fullscreen mode Exit fullscreen mode

For reference, this is how it's configured on Laravel Cloud.

Closing Thoughts

I plan to keep these starter kits aligned with upstream changes as much as possible. However, if official translation support is added upstream, I may discontinue these repositories.

The issue that motivated this work:

https://github.com/laravel/maestro/issues/168

However, we are already discussing the best implementation for this internally.

About the Translation Adapter

For translation synchronization between Laravel and the frontend, this project uses erag/laravel-lang-sync-inertia.

https://packagist.org/packages/erag/laravel-lang-sync-inertia

Special thanks to Er Amit Gupta for merging PRs related to the Svelte adapter and flat-key support.

Top comments (0)