Skip to content

Installing Themes ​

Introduction ​

Installing a theme takes three steps: require the package (or drop the theme into themes/), build its assets if it is a Vue theme, and activate it.

1. Require the theme ​

A theme requires kitloom/themes and the engine it renders with, so Composer installs them together with it:

bash
composer require kitloom/portfolio-theme
# pulls in kitloom/inertia and kitloom/themes
bash
composer require kitloom/blade-theme
# pulls in kitloom/blade and kitloom/themes

For the admin screen, add the package for your panel:

bash
composer require kitloom/themes-filament
bash
composer require kitloom/themes-nova

A theme without a package ​

A theme can also live in your application, in themes/{Theme}. List it in config/kitloom-themes.php, since there is no package to declare it:

php
// config/kitloom-themes.php
return [
    'all' => ['MySiteTheme'],
];

2. Set up the build (Vue themes) ​

A Blade theme has nothing to build — skip to step 3.

Vue themes are built with Vite. kitloom provides a Vite plugin that knows where the theme is — themes/ or vendor/ — and what it inherits from. Your vite.config.js:

js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import kitloomTheme, { themeEntry } from './vendor/kitloom/themes/vite/index.js';

const theme = process.env.APP_THEME || 'Portfolio';

export default defineConfig({
    plugins: [
        laravel({
            input: [themeEntry(theme)],
            buildDirectory: `build-${theme}`,
            refresh: true,
        }),
        kitloomTheme({ theme }),
        vue({
            template: {
                transformAssetUrls: { base: null, includeAbsolute: false },
            },
        }),
    ],
});

Add the theme's JavaScript dependencies and a script that builds every theme:

bash
npm install -D vite@^7 laravel-vite-plugin@^2 @vitejs/plugin-vue@^6
npm install vue@^3.5 @inertiajs/vue3@^1.3 axios

The theme's own imports are resolved from your application's node_modules, so install whatever the theme uses — Portfolio needs nothing beyond the three above; a theme with an icon sprite needs sharp and spritesmith. The skeletons' package.json lists everything.

json
// package.json
{
    "scripts": {
        "dev": "vite",
        "build": "vite build",
        "build:themes": "node vendor/kitloom/themes/vite/build-themes.js"
    }
}

Build:

bash
npm run build:themes          # every installed Vue theme
npm run build:themes MyTheme  # one theme
APP_THEME=MyTheme npm run dev # dev server for one theme

Each theme is built into its own directory, public/build-{Theme}, with its own manifest. That is what lets an administrator switch themes without a rebuild: @vite always reads the active theme's build.

Deploying

Run npm run build:themes in your deploy pipeline, so every installed theme is ready to be activated. A Vue theme that is not built cannot be activated — the screen marks it Not built yet.

See Building Assets for everything the plugin does.

3. Activate the theme ​

Open Appearance → Themes and click Activate on the theme's card. Or set the default in .env, which applies while nothing is selected in the admin:

ini
APP_THEME=Portfolio

On activation the theme's migrations run; on deploy, the active theme's migrations run with the site's php artisan migrate.

Removing a theme ​

bash
composer remove kitloom/blade-theme

If the removed theme was active, the site falls back to APP_THEME, then to kitloom-themes.fallback. Remove its build directory public/build-{Theme} too.

Running without a theme ​

The active theme's card has a Deactivate button. After a confirmation the site has no theme at all — not even APP_THEME or kitloom-themes.fallback — and every page answers with its data as JSON, for a headless frontend. The Themes screen says so above the cards; Activate on any card brings the rendered site back.