Adminix Documentation Help

Configuration

Panel configuration is stored in config/adminix.php.

return [ 'panel' => null, 'panels' => [], 'route_prefix' => [URL prefix for Adminix], 'admin_user_model' => [User model class], 'pages' => [Pages configuration], 'menu' => [Menu configuration], 'notification_bell' => null, 'table_views' => [ 'storage' => false, 'provider' => null, ], 'tenant_context' => [ 'provider' => null, ], 'app_title' => 'Adminix Panel', 'no_auth_access' => false, ];

Configuration elements

route_prefix - prefix for Adminix page URLs. Example: if the prefix is adminix, the users page URL will be https://domain.com/adminix/users.

panel - optional \AlexKudrya\Adminix\AdminixPanel object or array that groups the Adminix shell settings: path, guards, route middleware, menu, pages, default theme, application title, local/demo auth bypass, and notification bell. When panel is null, Adminix uses the legacy top-level keys such as route_prefix, pages, menu, app_title, and no_auth_access.

panels - optional array of multiple panels for one Laravel app. When this array is not empty, it takes precedence over panel and the legacy top-level route/page/menu keys. Array keys become stable panel keys for route names: the default panel keeps legacy route names such as adminix_page, while non-default panels use names such as adminix.ops.page. Each panel must use a unique key and path.

admin_user_model - Eloquent model for authenticated users. By default it is \App\Models\User::class.

pages - Adminix page configuration, described in Pages configuration. The package default is an empty array so installing Adminix does not require application-specific page classes to already exist.

menu - Adminix menu configuration, described in Menu configuration. Configure at least one menu link before exposing a real Adminix page.

notification_bell - optional NotificationBell instance for provider-backed admin notifications.

table_views - optional saved table view storage configuration. Set table_views.storage to true when you want Adminix to register the standard adminix_table_views migration and use the built-in database provider. Set table_views.provider to a TableViewProviderInterface class when saved views should use application-owned storage.

tenant_context - optional tenant context provider configuration. Set tenant_context.provider to a TenantContextProviderInterface class or bound implementation when the application wants to expose server-owned tenant context records to Adminix. This contract does not make browser route params authoritative. Adminix signs the active provider-approved tenant context into module endpoint contexts so stale or mismatched tenant selections are rejected, and injects active provider criteria into package-owned list/resource scopes.

app_title - title for the <title> tag in the <head> of Adminix pages.

no_auth_access - provides access to the admin panel without authorization when set to true. Use it only for local development or demo environments.

Safe default config

The published config starts without pages and menu links. Add pages and links explicitly in your application:

'pages' => [ \App\Adminix\Pages\UsersPage::get(), ], 'menu' => [ 'title' => 'AdminiX', 'links' => [ ['uri' => \App\Adminix\Pages\UsersPage::URI, 'title' => 'Users', 'icon' => 'bi bi-people-fill'], ], ],

Pages configuration

Menu configuration

Default panel object

Use AdminixPanel when the route shell should be configured as one object while keeping pages and menu PHP-first:

use AlexKudrya\Adminix\AdminixPanel; return [ 'panel' => AdminixPanel::make(env('ADMINIX_PREFIX', 'adminix')) ->guards(['web']) ->middleware(['web']) ->theme(AdminixPanel::THEME_SYSTEM) ->appTitle('Operations') ->menu([ 'title' => 'Operations', 'links' => [ ['uri' => \App\Adminix\Pages\UsersPage::URI, 'title' => 'Users', 'icon' => 'bi bi-people-fill'], ], ]) ->pages([ \App\Adminix\Pages\UsersPage::get(), ]), 'admin_user_model' => \App\Models\User::class, ];

guards() are appended to the Adminix auth and guest middleware and the first guard is used for login/logout. middleware() wraps the whole Adminix route group; include web unless the consuming application intentionally owns an equivalent session/CSRF stack. theme() accepts system, light, or dark and sets the initial rendered theme until the user changes it in the browser. noAuthAccess() still must be used only for local/demo surfaces.

Multiple panels

Use panels when one application needs separate Adminix surfaces with different paths, menus, pages, guards, middleware, or themes:

use AlexKudrya\Adminix\AdminixPanel; return [ 'panels' => [ 'default' => AdminixPanel::make('adminix') ->guards(['web']) ->appTitle('Operations') ->menu([ 'title' => 'Operations', 'links' => [ ['uri' => \App\Adminix\Pages\OrdersPage::URI, 'title' => 'Orders', 'icon' => 'bi bi-card-checklist'], ], ]) ->pages([ \App\Adminix\Pages\OrdersPage::get(), ]), 'support' => AdminixPanel::make('support-admin') ->guards(['support']) ->appTitle('Support') ->theme(AdminixPanel::THEME_LIGHT) ->menu([ 'title' => 'Support', 'links' => [ ['uri' => \App\Adminix\Pages\TicketsPage::URI, 'title' => 'Tickets', 'icon' => 'bi bi-inbox'], ], ]) ->pages([ \App\Adminix\Pages\TicketsPage::get(), ]), ], 'admin_user_model' => \App\Models\User::class, ];

The first route above renders under /adminix/*; the second renders under /support-admin/*. Adminix-generated links, forms, modal APIs, imports, exports, notification bell endpoints, progress polling, and list reorder endpoints use the current panel automatically. Use php artisan adminix:doctor --strict to catch invalid adminix.panels, duplicate panel keys, duplicate paths, and invalid nested menu/page/module configuration.

Tenant context provider

Use TenantContextProviderInterface to expose the current tenant and the tenant choices that an application owns on the server:

use AlexKudrya\Adminix\Contracts\TenantContextProviderInterface; use AlexKudrya\Adminix\Dto\TenantContextDto; use AlexKudrya\Adminix\Dto\TenantContextRequestDto; use AlexKudrya\Adminix\Dto\TenantContextResultDto; class AppTenantContextProvider implements TenantContextProviderInterface { public function currentTenantContext(TenantContextRequestDto $request): ?TenantContextDto { $tenant = auth()->user()?->currentTenant; return $tenant ? new TenantContextDto( key: (string) $tenant->id, label: $tenant->name, criteria: [['tenant_id', '=', $tenant->id]], ) : null; } public function tenantContexts(TenantContextRequestDto $request): TenantContextResultDto { $records = auth()->user() ?->tenants() ->get() ->map(fn ($tenant) => new TenantContextDto( key: (string) $tenant->id, label: $tenant->name, criteria: [['tenant_id', '=', $tenant->id]], )) ->all() ?? []; return new TenantContextResultDto($records, count($records)); } }

Register it in config:

'tenant_context' => [ 'provider' => App\Adminix\AppTenantContextProvider::class, ],

The provider must derive tenant membership and criteria from authenticated server-side state. Use Tenant Switcher when an Adminix page needs a rendered selector for these provider-owned records. Do not use browser-submitted tenant IDs as authority; signed endpoint context verifies the active provider result, and provider criteria are injected server-side for Adminix-owned list/resource scopes. Run php artisan adminix:doctor --strict to validate the configured provider class.

Last modified: 01 July 2026