Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

croftCoder's avatar

How To Add Theme To Laravel Project

i want to create a laravel theme package that will load views based on selected theme in theme config file, such that if selected theme is shop, return view('home.index) will automatically load view in resources/views/shop/home/index.blade.php, likewise if mart it'll load views from resources/views/mart folder. this is what i have so far:

ThemeViewFinder.php

<?php

namespace Vendora\Theme;

use Illuminate\View\FileViewFinder;

class ThemeViewFinder extends FileViewFinder
{
    // DON'T KNOW WHAT TO DO
}

ThemeServiceProvider.php

<?php

namespace Vendora\Theme\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class ThemeServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // WHAT TO DO
    }

    public function register()
    {
        // WHAT TO DO
    }
}

themes.php config file

<?php

return [
    'default' => 'shop',

    'themes' => [
        'shop' => [
            'name'        => 'Default Shop Theme',
            'assets_path' => 'public/themes/shop/assets',
            'views_path'  => 'resources/views/shop',

            'vite'        => [
                'hot_file'                 => 'shop-default-vite.hot',
                'build_directory'          => 'themes/shop/default/build',
                'package_assets_directory' => 'resources/shop',
            ],
        ],
    ],


    'admin-default' => 'shop-admin',

    'admin-themes' => [
        'shop-admin' => [
            'name'        => 'Default Shop Admin Theme',
            'assets_path' => 'public/themes/shop-admin/default',
            'views_path'  => 'resources/views/shop-admin',

            'vite'        => [
                'hot_file'                 => 'shop-admin-default-vite.hot',
                'build_directory'          => 'themes/shop-admin/default/build',
                'package_assets_directory' => 'resources/shop',
            ],
        ],
    ],
];

any help? not an expert in laravel...

0 likes
3 replies
NotTaken's avatar

A hacky way you could do it would be to use something like:

config(['view.paths' => [resource_path('views/my_theme')]]);

Maybe in a middleware configured in your routes? No idea about the vite configuration side though.

martinbean's avatar

@croftcoder I’d use a view namespace for this.

Users would reference the views using a namespace prefix:

return view('theme::home');

You can then declare what directories Laravel should look in for these views:

View::addNamespace('theme', [
    resource_view('views/themes/default'),
]);

So theme::home would point to resources/views/themes/default/home.blade.php

If you want the “theme” to be dynamic, then you can just dynamically set the path depending on the theme selected by the user. You could do this in middleware or something:

class SetThemeViewNamespace
{
    public function handle(Request $request, Closure $next)
    {
        $user = $request->user();

        View::addNamespace('theme', array_filter([
            $user && $user->theme ? sprintf('resources/views/themes/%s', $user->theme) : null,
            resource_path('views/themes/default'),
        ]));

        return $view($request);
    }
}

This will register two paths that Blade will look for in turn:

  1. First, the specific theme the user has selected.
  2. Secondly, it will then fallback to a “default” theme.

I use this approach myself in a multi-tenant CMS where each website can have their own theme, or where I can just override specific views for a particular website if it needs something slightly different.

1 like
croftCoder's avatar

@martinbean thanks. i get the idea and i tried implementing it woeks just that it doesn't load views in other theme folders but only the default. my folder structure is something like so resources/views/shop/home/index.blade.php with shop as theme folder. another is resources/views/mart/home/index.blade.php. this is how i'm calling the view function in the controller: return view('theme::home.index');. i tried to dd on the path and it shows the correct path but not loading from it

Please or to participate in this conversation.