Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Zora Laravel Package

jetstreamlabs/zora

Zora is a Laravel package from Jetstream Labs that simplifies adding AI-powered features to your application. It offers a clean, developer-friendly API and sensible defaults so you can integrate intelligent workflows quickly while keeping your code expressive.

Deep Wiki
Context7

Getting Started

Zora bridges Laravel's lang/ directory and your JavaScript bundle. Instead of duplicating strings in Vue/React and PHP, you keep one source of truth in Laravel and let Zora emit it as a JS-importable asset.

Minimal setup:

  1. Install the package:

    composer require jetstreamlabs/zora
    
  2. Publish its config (tag name may vary — check php artisan vendor:publish output):

    php artisan vendor:publish --provider="JetstreamLabs\Zora\ZoraServiceProvider"
    
  3. Generate the translation asset:

    php artisan zora:generate
    

    This typically writes JSON (or a JS module) into resources/js/ or public/ — confirm the target path in config/zora.php.

  4. Import it in your frontend:

    import translations from '@/zora/en.json';
    // or, if Zora exposes a helper:
    import { trans } from '@/zora';
    

Where to look first: the published config/zora.php (source paths, output path, locales, format) and the generated file itself — its shape tells you exactly how to consume keys. Then check the package's service provider for registered commands and any Blade directive or Vite hook.

First use case: take a hardcoded string in a Vue component ("Save changes"), move it to lang/en/messages.php under 'save' => 'Save changes', regenerate, and swap the literal for trans('messages.save'). Once that works, the rest is scaling.

Implementation Patterns

Generate at build time, not runtime. Wire zora:generate into your asset build so translations can't drift:

// package.json
"scripts": {
  "dev": "php artisan zora:generate && vite",
  "build": "php artisan zora:generate && vite build"
}

Or add it to composer.json post-autoload-dump / a deploy script. Avoid generating on every request — treat the output as a compiled artifact.

Per-locale files with dynamic import. If Zora emits one file per locale, lazy-load the active one:

const locale = document.documentElement.lang || 'en';
const messages = await import(`@/zora/${locale}.json`);

This keeps bundles small and supports locale switching without a full reload.

Bridge Laravel's locale into JS. Share the current locale from Blade or Inertia:

<script>window.__LOCALE__ = @json(app()->getLocale());</script>
// Inertia middleware
'locale' => app()->getLocale(),

Then hydrate your i18n library (vue-i18n, react-i18next) from Zora's output and set the active locale from that value.

Nested keys and dot notation. Laravel's lang/en/messages.php with ['auth' => ['failed' => '...']] should map to messages.auth.failed. Decide early whether your JS trans() helper resolves dot paths itself or whether you flatten keys at generation time — pick one convention and enforce it across the team.

Reuse existing i18n libraries. Zora's job is producing the data; let vue-i18n or i18next handle interpolation, pluralization, and fallbacks. Feed Zora's output in as the message catalog rather than building a bespoke trans() from scratch.

Watch mode in development. If Zora ships a --watch flag, use it alongside Vite. If not, add a small filesystem watcher on lang/ in your dev script so edits to PHP translation files trigger regeneration and HMR.

CI/deploy checklist. Run zora:generate in the pipeline after composer install and before npm run build. If you commit generated files, add a CI step that regenerates and fails on a dirty diff — that catches developers who edited lang/ but forgot to regenerate.

Gotchas and Tips

Stale output is the #1 failure mode. The generated asset is a snapshot. Changing lang/en/foo.php and reloading won't reflect anything until you regenerate. If a string "won't update," check the generated file before debugging the frontend.

Escaping and HTML. Laravel's __() doesn't escape by default, but JSON serialization will faithfully carry quotes, apostrophes, and < characters. If you render translations with v-html or dangerouslySetInnerHTML, sanitize on the PHP side or avoid the pattern entirely.

Pluralization and placeholders. PHP's trans_choice and :name placeholders are Laravel-specific syntax. Confirm whether Zora transforms these into ICU/vue-i18n format or passes them through raw — if raw, your JS library won't understand :count or | plural separators. Handle this in a formatter layer or at the translation-file level.

Locale fallback. Laravel falls back to fallback_locale when a key is missing; your JS side won't unless you configure it. Either merge fallback-locale messages into each locale's output at generation time, or configure your i18n library's fallbackLng to match config('app.fallback_locale').

Config path quirks. Packages like this often default to lang/ (Laravel 8 style) while newer apps use lang/ at the project root vs. resources/lang/. Verify config/zora.php points at the right directory for your Laravel version; a silently empty generated file usually means a wrong source path.

Caching. If Zora caches compiled translations, php artisan cache:clear (and possibly config:clear) resolves "I regenerated but nothing changed." Also clear any Vite/Webpack persistent cache when the output path changes.

Don't ship every locale to every user. Large apps with many locales generate big files. Emit per-locale assets and lazy-load, or split by namespace if the package supports it. A single 500 KB translations.js in the main bundle is a common accidental regression.

Extension points to look for: custom output formatters (JS module vs. JSON vs. TS types), configurable key-flattening, namespace grouping, and a Blade @zora directive or Vite plugin. If the defaults don't fit, subclassing the generator or wrapping the command in your own artisan command is usually cleaner than post-processing files.

Low-activity package caution. With modest adoption and a single recent release, pin the version ("jetstreamlabs/zora": "^1.0") and read the generator source before relying on it. The surface area is small enough that forking or wrapping it is viable if maintenance lags — the core logic (walk the lang/ tree, emit JSON) is straightforward and worth understanding regardless.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings