Configuration
The LaravelUi5 configuration file can be published via
php artisan vendor:publish --tag=ui5-configIt defines the foundational settings for the LaravelUi5 platform: the UI5 version, the metadata and routes exposed to app manifests, the registry and context-factory implementations, the middleware stacks on the two route groups, the auth switch, the artifact-resolver chain, and the modules your host loads.
Every key below appears in the published file with its own comment block; this page is the same material with the reasoning spelled out.
The following sections provide a structured breakdown of each configuration key, its purpose, and how it influences the system’s behavior.
OpenUI5 Framework Version
Key version
The OpenUI5 version an app loads from the CDN in built mode — unless the app names its own:
- An app's own version wins.
ui5:appreadsframework.versionfrom the source project'sui5.yamland writes it into the app's base class (getUi5Version());--refreshkeeps it current. That happens forframework.name: OpenUI5only — the bootstrap loads from the OpenUI5 CDN — and an app whoseui5.yamlnames no version returnsnulland uses this key. - Scaffolding.
ui5:assemblewrites this value as the generated app'sminUI5Version. - Workspace mode is unaffected: the UI5 dev server serves the framework.
Must be a valid version tag from the official UI5 CDN (e.g., "1.120.5").
Manifest Metadata
Key meta
Optional key/value pairs merged into the laravel.ui5.meta block of every generated manifest.json, alongside the default 'generator' => 'LaravelUi5 Core' — which always wins on a key conflict.
'meta' => [
'build' => env('APP_BUILD'),
'environment' => app()->environment(),
],Leave it empty unless you need to stamp build or environment facts into your manifests. It is a flat map, read once per manifest build.
UI5 App Routing
Key routes
Allows you to define Laravel route names that will be exposed to the UI5 application's manifest.json. Useful for authentication routes or navigation purposes.
The entries are automatically resolved via Laravel's route(...) helper and injected into the laravel.ui5.routes section of the generated manifest.
Rules
Values must be valid Laravel route names.
URLs may be relative or absolute depending on routing config.
Example provided in comments:
php'routes' => [ 'login' => 'user.login', 'logout' => 'user.logout', 'profile' => 'user.profile', 'home' => 'dashboard.index', ]
UI5 Registry Implementation
Key registry
Value \LaravelUi5\Core\Ui5\Ui5Registry::class
This option controls which implementation of the Ui5RegistryInterface is used by the LaravelUi5 system.
Ui5Registry is the in-memory default: it boots by reflecting every registered module and artifact on each request. That is the right trade for development — a code change is visible immediately, with nothing to invalidate.
To swap it, point this key at another Ui5RegistryInterface implementation. That is the seam the SDK uses: its SdkRegistry layers database-backed state on top of the same two-pass boot, and pairs with a cached registry that reads a warm snapshot instead of reflecting. Registry selection is a single class-string here — there is no second key to set.
Registered UI5 Modules
Key modules
A flat list of module classes — each implementing Ui5ModuleInterface — that this host loads. A module is a cohesive functional unit: a UI5 application or library, plus its artifacts (cards, charts, reports, tiles, actions).
'modules' => [
\Showcase\ShowcaseModule::class,
],Only the class matters; the registry keys each module by the namespace it declares, and artifacts are routed by their own namespace and version (ui5/app/com/example/[email protected]/index.html), never by a key in this array.
Infrastructure modules do not belong here. Modules contributed by installed packages — Core's own CoreModule, and whatever your packages register — are collected automatically at boot and merged ahead of this list. Listing them again is redundant at best.
What this array is, is a product decision: only modules named here are visible and supported. That is why the step stays manual even though the package could technically register itself — see Register the app with your host.
Per-Request Context
Key context_factory
Value \LaravelUi5\Core\Runtime\CoreContextFactory::class
The implementation of Ui5ContextFactoryInterface that builds the per-request Ui5ContextInterface (Core's own is Ui5CoreContext). Core's factory resolves two things — the addressed artifact and the request locale — because that is all a stateless Core knows.
Swap it to enrich the context. This is the seam the SDK uses: its factory adds tenant, actor and principal, which is what lets an SDK provider method-inject a context that can answer who is asking.
A context of your own implements the whole interface — artifact(), locale() and slot(). changed in 3.0slot() is new on the interface; see Reading a slot anywhere for the one-liner.
Route Middleware
Key middleware
The stack applied to the ui5/* route group — app entry points, manifests, cards, dashboards, reports, resources, actions and assets:
'middleware' => [
'web',
\LaravelUi5\Core\Http\Middleware\ResolveRequestLanguage::class,
\LaravelUi5\Core\Http\Middleware\ResolveUi5Context::class,
\LaravelUi5\Core\Http\Middleware\EnsureUi5Authenticated::class,
],ResolveRequestLanguage sets the request's language from sap-language, else Accept-Language — the language part only, so de-AT becomes de — and with it app()->getLocale(). It runs before the context is built, which carries the language. ResolveUi5Context binds the per-request context into the container — every artifact resolution downstream depends on it, so it must come before anything that reads it. EnsureUi5Authenticated is the opt-in turnstile described under auth_enabled.
Append your own middleware; think hard before removing either of these.
OData Route Middleware
Key odata_middleware
The stack applied to the odata/* route group:
'odata_middleware' => [
'web',
\LaravelUi5\Core\Http\Middleware\ResolveRequestLanguage::class,
\LaravelUi5\Core\Http\Middleware\FetchCsrfToken::class,
\LaravelUi5\Core\Http\Middleware\ResolveODataEndpoint::class,
\LaravelUi5\Core\Http\Middleware\EnsureODataAuthenticated::class,
],Each entry earns its place:
| Middleware | Why it is there |
|---|---|
ResolveRequestLanguage | sets the request's language from the client — see below |
FetchCsrfToken | implements the SAP Fiori X-CSRF-Token: Fetch handshake |
ResolveODataEndpoint | parses {namespace}@{version}, binds the resolved ODataServiceInterface; an unknown namespace is a 404, an artifact without OData a 400 — both as an OData error envelope with OData-Version: 4.0 |
EnsureODataAuthenticated | answers an honest 401 with an OData error envelope |
⚠️ Do not replace the OData auth middleware with Laravel's stock
auth. The default guest response is a302 → /login, and the UI5 v4 model'sfetchfollows it transparently, parses the login HTML, finds noOData-Versionheader and throws a protocol error that has nothing to do with the real problem.EnsureODataAuthenticatedexists to make an auth failure look like an auth failure.
The request language
since 3.0ResolveRequestLanguage reads the language the UI5 client asks for and sets it on the request and on the app, so $context->locale(), __() and anything that reads app()->getLocale() agree for the rest of the request:- the
sap-languagequery parameter, if the app wrote one into its service URL; - else the first entry of
Accept-Language— which OpenUI5 sends on every OData request, code-list loads included, taken fromsap-ui-language; - else nothing: the app's configured locale stays.
The value is a language, not a locale — the primary subtag, lower case: de-AT and DE both become de. Laravel's translator does not fall back from de_AT to de, and texts are kept per language. A value that is not a language tag (SAP's internal codes such as 1Q) is ignored and the next channel decides.
Keep it first after web, ahead of anything that builds the context — on an SDK host, ahead of BindSdkContextForOData.
⚠️ A published config is not updated by
composer update. A host that publishedconfig/ui5.phpbefore 3.0 adds the line by hand; without it, OData responses ignore the client's language.
The locale slot is a separate value and is not touched: it is read through the slot pipeline, from the query string or its default.
Authentication Enforcement
Key auth_enabled
Default env('ENABLE_AUTH_4_UI5', true)
The master switch for both auth middlewares. Set it false and the gate is inert — every request passes, which is convenient locally and wrong in production.
It is worth being precise about what this does and does not control. Core owns no identity: no user model, no credential check, no session, no login page. The middleware ensures a result someone else produced. Everything it reads is host-supplied:
| Core reads | Owned by |
|---|---|
Auth::check() | your configured guard |
route('login') | your route |
config('ui5.auth_enabled') | this key |
$module->requiresAuth() | the artifact's own module |
So the gate is opt-in twice over: with no login route, or with this key false, it is a no-op.
Artifact Resolvers
Key artifact_resolvers
Value [\LaravelUi5\Core\Runtime\PathBasedArtifactResolver::class]
An ordered chain mapping an incoming request path to a registered artifact. The default resolver covers the {namespace}@{version} convention every ui5:* generator produces, which is all a Core-only host needs.
Hosts and packages append to the chain to serve additional URL schemes — the SDK adds a resolver for shell-context requests, for instance. Order matters: the first resolver that returns an artifact wins.
OData Configuration
The OData engine has its own config file, published separately by laravelui5/odata — none of its keys live in config/ui5.php. See the laravelui5/odata documentation.
One key there is Core's, though: Core's service provider forces odata.register_routes = false at registration time, so it can install the OData routes itself with the odata_middleware stack above. Do not set it back to true — you would get double-registered routes, and the second set would have no auth and no CSRF handling.