Installation
composer require becklyn/translations
Add to config/bundles.php (if using Symfony):
return [
// ...
Becklyn\TranslationsBundle\BecklynTranslationsBundle::class => ['all' => true],
];
Basic Configuration
Add to config/packages/becklyn_translations.yaml:
becklyn_translations:
cache_version: 1
First Use Case
config/packages/becklyn_translations.yaml:
becklyn_translations:
extract:
frontend:
messages:
- app.*
- auth.*
php bin/console becklyn:translations:extract
<script src="{{ asset('_v/translations/frontend.js') }}"></script>
window.translations = window.translations || {};
window.translations.init('frontend', translations);
Translation Extraction
php bin/console becklyn:translations:extract
post-update-cmd in composer.json for CI/CD pipelines:
"scripts": {
"post-update-cmd": [
"@php bin/console becklyn:translations:extract"
]
}
Namespacing Translations
frontend, admin):
becklyn_translations:
extract:
frontend:
messages: [app.*, auth.*]
admin:
messages: [admin.*, settings.*]
// Load frontend translations
translations.init('frontend', translationsFrontend);
// Load admin translations (if needed)
translations.init('admin', translationsAdmin);
Integration with Frontend Frameworks
import { useTranslations } from '@/composables/translations';
const { t } = useTranslations('frontend');
const TranslationContext = createContext();
// Wrap app with <TranslationContext.Provider value={translations}>
Dynamic Translation Updates
php bin/console becklyn:translations:invalidate-cache
cache_version in config and redeploy.Laravel-Specific Setup
php artisan vendor:publish --provider="Becklyn\TranslationsBundle\BecklynTranslationsBundle" --tag="config"
routes/web.php:
Route::get('_v/translations/{namespace}.js', \Becklyn\TranslationsBundle\Controller\TranslationController::class)
->where('namespace', 'frontend|admin');
Custom Extraction Logic
$this->app->bind(
\Becklyn\TranslationsBundle\Extractor\ExtractorInterface::class,
\App\Services\CustomExtractor::class
);
Localization with JavaScript
i18next alongside the bundle:
i18next.init({
resources: {
en: { translation: translations }
}
});
Testing
$this->app->instance(
\Becklyn\TranslationsBundle\Loader\TranslationLoaderInterface::class,
new \App\Tests\MockTranslationLoader()
);
Cache Invalidation
cache_version after manual translation edits will serve stale JS.Wildcard Overuse
*.*) may extract unused translations, bloating JS bundles.auth.* instead of *.*).Namespace Collisions
frontend for both PHP and JS) can cause confusion.frontend-php, frontend-js).Route Conflicts
/_v/translations/) may clash with existing routes.config/packages/becklyn_translations.yaml:
_import.becklyn_translations:
resource: '@BecklynTranslationsBundle/Resources/config/routes.yaml'
prefix: /assets/translations/
Missing Translations
php bin/console becklyn:translations:extract --verbose
app.welcome vs. app.*).JS Not Loading
curl http://localhost/_v/translations/frontend.js
Cache Issues
php artisan cache:clear
php artisan config:clear
var/cache/dev/ (or bootstrap/cache/ in Laravel).Versioning
cache_version (e.g., 1.0.0 for major updates, 1.0.1 for minor fixes).Environment-Specific Configs
# config/packages/becklyn_translations_{env}.yaml
becklyn_translations:
extract:
frontend:
messages: [app.%, auth.*] # % = current env
Performance
becklyn_translations:
extract:
frontend:
locales: [en, fr] # Only extract for these locales
Extending Functionality
// app/Extractor/CustomFilter.php
public function filter(array $messages): array {
return array_filter($messages, fn($key) => str_contains($key, 'custom.'));
}
AppServiceProvider:
$this->app->make(\Becklyn\TranslationsBundle\Extractor\Extractor::class)
->addFilter(new \App\Extractor\CustomFilter());
Local Development
config/packages/becklyn_translations.yaml:
becklyn_translations:
cache_version: dev # Forces cache busting
How can I help you explore Laravel packages today?