Adding CSS and JS assets
Shopper can load extra stylesheets and Javascript files located in thepublic/ directory.
Via configuration
You may register assets to be loaded in the Control Panel using thescripts and stylesheets keys of the resources in the config/shopper/admin.php config file. This will accept an array of links.
You can load the links locally or using cdn. They will be automatically loaded in the control panel
public/css/admin.css and public/js/admin.js respectively for local links.
Via service provider
You can also register additional stylesheets and scripts programmatically from any service provider using the fluent API:Both approaches can be used together. Assets registered via the config file and via the service provider are merged automatically.
Customize Shopper theme
Shopper ships with a pre-compiled CSS file (dist/shopper.css) that works out of the box. However, if you want to customize the admin panel styles using Tailwind CSS, you can build your own theme by importing Shopper’s theme.css file.
Shopper provides a dedicated theme.css entry point that handles all internal imports (Tailwind, Filament, Shopper base styles, source detection, and plugins) so you don’t have to wire them up manually.
Setting up Tailwind CSS for your project
Install Tailwind CSS v4 with the Vite plugin and the required plugins:@tailwindcss/vite plugin to your vite.config.js:
Creating the theme file
Create aresources/css/shopper.css file and import Shopper’s theme entry point:
theme.css file already includes Tailwind, Filament CSS, Shopper base styles and components, source detection for all required Blade views, and the @tailwindcss/forms and @tailwindcss/typography plugins. You don’t need to configure any of that yourself.
To add your own source paths (custom Livewire components, app modules, etc.) or custom styles, add them after the import:
Load theme
In yourAppServiceProvider or any other provider, register the Vite theme in the boot method:
Branding Logo
By default, the Laravel Shopper logo is used on the login page and in the sidebar header. You have several options to replace it with your own brand.Via configuration
The simplest approach is to set thebrand key in your config/shopper/admin.php configuration file with a path to your logo image:
asset() helper function, so the file should be in your public/ directory.
Via service provider
For more control, use thebrandLogo() method on the Shopper facade. You can pass an HTML string, a closure that returns a string, or a closure that returns a View instance:
The priority order is:
Shopper::brandLogo() > config('shopper.admin.brand') > default Shopper logo.Render hooks
Shopper allows you to render Blade content at specific points in the admin panel layout. This is useful for integrating third-party packages that require Blade components in the layout, such as Flux UI, Wire Elements Modal, or Laravel Notify.If you are familiar with Filament’s render hooks, you already know how this works. Shopper’s render hooks follow the same concept.
Registering a render hook
To register a render hook, call theShopper::renderHook() method from a service provider’s boot method. The first argument is the hook position (using the RenderHook enum), and the second is a closure that returns HTML:
ShopperPanel instance, you can chain multiple calls:
Available render hooks
| Hook | Enum | Description |
|---|---|---|
| Head Start | RenderHook::HeadStart | After the meta tags, before Filament styles and Shopper theme |
| Head End | RenderHook::HeadEnd | End of <head>, after all styles and scripts |
| Body Start | RenderHook::BodyStart | Start of <body>, before any content |
| Body End | RenderHook::BodyEnd | End of <body>, after Filament scripts |
| Content Start | RenderHook::ContentStart | Start of the main content area (inside the layout, after the sidebar) |
| Content End | RenderHook::ContentEnd | End of the main content area |
Example: Wire Elements Modal
Example: Flux UI
Example: Laravel Notify
Adding control panel routes
If you need to have custom routes for the control panel:-
Create a routes file. Name it whatever you want, for example:
routes/shopper.php -
Then add this to your
shopper/routes.phpfile so that all routes are dynamically loaded: -
If you want to add middleware to further control access to the routes available in this file you can add in the key
middlewareof theshopper/routes.phpfile