Livewire Inline Translation

darvis/livewire-inline-translation is a Laravel package with one Livewire component that shows a translation and lets an authorised user edit it on the page itself. They click the text, a modal opens, and the new value is stored in the translations table for the current locale.

It is for a site where a client or an editor wants to change wording without a CMS and without asking a developer. Your language files stay the source for every text nobody has edited.

Install it in three lines

composer require darvis/livewire-inline-translation
php artisan migrate
<div id="inline-translation-modals"></div>

The last line goes in your layout, once, before the closing body tag. Installation has every step and a check that it works.

Requirements

PHP 8.2 or higher, Laravel 11, 12 or 13, and Livewire 3 or 4. Livewire brings Alpine.js, which the modal uses. A database, because the edited values are stored there.

Your first editable translation

resources/views/welcome.blade.php:

<h1><livewire:inline-translation translation-key="website.welcome" /></h1>

website.welcome is looked up in the database first and falls back to __('website.welcome'), so the page reads the same as before until someone edits it. Someone who is logged in on the configured guard sees a dashed blue underline and can click the text. Everyone else gets the text without the underline, the click handler or the modal.

Where the text lives

Situation Where the text comes from
Not edited yet your language file, through __('website.welcome')
Edited once a row in the translations table, one per locale
Language file changed afterwards the database row still wins; delete the row to fall back to the file

What it does not do

  • No per user or per key permissions. There is one guard check; you narrow it by overriding isAuthorized().
  • No revision history, no approval flow and no translation memory.
  • No sanitising. The stored value is rendered as HTML, so whoever may edit can put any markup on the page.
  • It does not change __(). Only the component reads the database; see Usage.
  • No JSON translation strings: a key needs the form group.key.

Read on

  • Installation: from composer require to a text you can click, with a check that it works
  • Usage: one complete example, the HTML editor, several locales and where the component does not belong
  • Configuration: the two settings, choosing a guard and narrowing who may edit
  • How it works: the lookup order, the authorisation check, saving per locale and the modal
  • API reference: the component, the model, the table, the config keys and the publish tags
  • Testing: test a page with an editable translation in your own application
  • Troubleshooting: from the symptom to the cause and the fix
  • FAQ: short answers to the questions people ask first