weglot/translate-bundle
A Symfony bundle that integrates Weglot’s website translation service, making it easy to add multilingual support with minimal configuration. Manage translations through Weglot and serve localized content automatically.
Read this first: weglot/translate-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle subclass, a DependencyInjection/Configuration.php tree, and Twig templates — none of which Laravel's container will boot. It also has 10 stars and is archived. So "getting started" for a Laravel developer is really evaluating whether to copy its ~50 lines of behavior rather than installing it.
Where to look in the repo, in order:
README.md — install snippet and the config block.DependencyInjection/Configuration.php — the authoritative list of options (api_key, original_language, destination_languages, cache, exclusions). Trust this file over the README; they drift, especially on an archived repo.Resources/views/ — the Twig template that emits the Weglot <script> tag. This is the only part you actually want.Twig/ extension — typically a helper for language switchers or hreflang links.Minimal Symfony steps (for reference), and the Laravel equivalent:
# Symfony: config/packages/weglot_translate.yaml
weglot_translate:
api_key: '%env(WEGLOT_API_KEY)%'
original_language: 'en'
destination_languages: ['fr', 'de']
// Laravel: config/weglot.php — you write this yourself
return [
'api_key' => env('WEGLOT_API_KEY'),
'original_language' => 'en',
'destination_languages' => ['fr', 'de'],
'excluded_paths' => ['admin/*', 'api/*', 'checkout/*'],
];
Then a Blade component in your layout:
{{-- resources/views/components/weglot.blade.php --}}
@unless (request()->is(...config('weglot.excluded_paths')))
<script type="text/javascript" src="https://cdn.weglot.com/weglot.min.js"></script>
<script>
Weglot.initialize({
api_key: '{{ config('weglot.api_key') }}',
originalLanguage: '{{ config('weglot.original_language') }}',
languages: [/* ... */],
});
</script>
@endunless
First real use case: a content-heavy marketing or docs site where copy lives in a CMS or database and you don't want to maintain parallel lang/fr/… files. Weglot translates the rendered DOM (or via its API) and the bundle's only job is plumbing: key, language list, snippet, switcher. That plumbing is small enough to own.
Configuration-as-code, secrets by env. Whatever framework, keep the API key in env()/secrets and the language list in version control. The bundle does this; mirror it. One config file becomes the single source of truth for the snippet, the switcher, and hreflang — otherwise those three drift and your SEO breaks.
Server-render the language switcher and hreflang, not the JS. The bundle exposes languages via Twig; in Laravel build them from the same array:
@foreach (config('weglot.destination_languages') as $lang)
<link rel="alternate" hreflang="{{ $lang }}" href="{{ url()->current() }}?lang={{ $lang }}">
@endforeach
Crawlers and Weglot.switchTo() both need this. Emitting alternates only from JS is a known weakness of snippet-only setups.
Exclusions belong in middleware or a layout conditional, not scattered attributes. Path exclusions (/admin, /api, /checkout) go in one place; element exclusions use data-wg-notranslate on things Weglot must not mangle — prices, usernames, code blocks, order numbers:
<span data-wg-notranslate>{{ $order->reference }}</span>
Adopt a clear ownership split. The dev owns: snippet, language list, exclusions, hreflang, caching headers. The content team owns: everything inside the Weglot dashboard. This is the biggest mental shift from Laravel's __()/lang/ workflow — translations are not in your repo, and you cannot code-review them.
Integration tip — don't mix strategies on one page. If a view uses __('auth.failed') and Weglot is enabled, Weglot may translate the already-translated string, or translate English fallbacks inconsistently. Decide per surface: app UI strings through lang/, marketing pages through Weglot.
Testing. Assert the snippet and hreflang tags exist in feature tests; do not assert translated copy — it arrives from Weglot's CDN and varies. In a Symfony project that means a WebTestCase hitting the homepage; in Laravel, a get('/')->assertSee('weglot.min.js', false).
composer require weglot/translate-bundle pulls Symfony framework contracts and registers nothing in Laravel — no auto-discovery, no ServiceProvider, no config/weglot.php. If you tried it and saw nothing happen, that's expected. Copy the behavior instead.Configuration.php and the Twig templates directly. If the snippet doesn't appear, the usual cause is that the bundle's template isn't included in your base layout, or the bundle never registered.data-wg-notranslate or by excluding those routes.config/app.php's locale or your Route::domain('{locale}.…') prefixes. Keep an explicit map — mismatches here silently break switchers and hreflang.data-wg-notranslate state. Clear your app cache and the Weglot dashboard cache after changing destination languages; cache:clear in Symfony/Laravel does not touch Weglot's.Route::domain() setups require different hreflang and canonical handling than subdirectory setups. Changing later is painful.Weglot.on('initialized'), Weglot.switchTo(lang), Weglot.getCurrentLang() — the bundle is a thin wrapper, so whatever framework you use, budget your time here.How can I help you explore Laravel packages today?