Automatic translation
composer require langsys/langsys-php-laravel Tagged mode (@t / t()) covers exactly what you wrap. TranslateResponse is the automatic mode — it runs the SDK’s page translator over the rendered HTML, translating every text node and translatable attribute (placeholder, alt, aria-label, …) with no @t at all. It’s the only way to cover text Alpine injects from a JS expression, which never becomes a DOM node you can wrap:
<span x-text="'Save changes'"></span><button :aria-label="open ? 'Collapse' : 'Expand'">…</button>It is opt-in and applies to nothing until you attach it:
// routes/web.php — per route or group, never globalRoute::middleware('langsys.translate-page')->group(function () { Route::get('/', HomeController::class);});LANGSYS_TRANSLATE_RESPONSE=trueOnly text/html responses are touched. JSON, redirects, streamed and file responses pass through untouched — which is what keeps Livewire and Inertia XHR round-trips out automatically. Scope it further with only / except path patterns in config/langsys.php (except wins), and set a category to namespace everything the page registers.
Newly discovered phrases are queued and flushed after the response, exactly as they are for t() / @t — the same terminable middleware and Octane listener drain both. Requires langsys/langsys-php ^1.3; before that, page registration made blocking HTTP calls mid-render.
Caching is off by default and should usually stay off. Translated output is keyed by a hash of the source HTML, so a page carrying a CSRF token or a timestamp produces a new key every render. Enable it only for genuinely static, high-traffic HTML.
Excluding a subtree
Section titled “Excluding a subtree”Two markers, and the difference is not cosmetic:
<pre translate="no">composer require langsys/langsys-php-laravel</pre> {{-- nobody translates this --}}<div data-notrans>{{ $userSuppliedHtml }}</div> {{-- Langsys skips it --}}translate="no"is standards HTML, so browser translation features (Chrome, Safari, Edge “translate this page”) honour it too. Use it for code samples, brand names, identifiers — anything no translator, human or machine, should touch.data-notransexcludes the subtree from Langsys only; a reader’s browser-translation is still free to act on it. Use it for content that’s already resolved, or that you handle yourself.
Presence is intent for both: a bare data-notrans excludes, and only ="false" or ="0" opts back in (trimmed, case-insensitive).