Compile theme SCSS with brand settings
Every time the admin saves branding, hostware recompiles your theme's SCSS with their chosen colours, radius and Google Fonts baked in before Bootstrap loads. The result is written to /public/assets/css/theme-<vendor>-<name>-sc<id>.min.css, one file per sales channel, and served ahead of your static styles.
Themes opt in to this by placing an SCSS entry file at public/css/style.scss and using !default on their brand-tied variables so the injected values win.
The SCSS entry file
Create public/css/style.scss. This is the only file the pipeline reads directly; it can @import anything else under public/css/.
// public/css/style.scss
@import "bootstrap/functions"; // needed before your overrides
@import "variables"; // your brand-tied overrides
@import "bootstrap/bootstrap"; // full Bootstrap
@import "theme"; // your refinementsMake brand tokens overridable
The compile pipeline prepends the admin's branding values as SCSS variables at the very top of style.scss. For those prepended values to win, every brand-tied variable in your _variables.scss must use !default. Without it, your line is a re-assignment that overrides whatever was injected.
// Correct - admin colours win
$primary: #175cd3 !default;
// Wrong - admin colours are ignored
$primary: #175cd3;Any custom variable that reads from a brand token, for example $my-blue: $primary, automatically follows the admin's choice.
What the pipeline injects
Colours (primary, secondary, success, danger, warning), page surfaces (body background and text, card background and text), border colour and radius, and both primary and secondary font families are all set from the admin's branding form. When a font is picked, the pipeline also writes @font-face rules for the locally-downloaded *.woff2 weights so the storefront pulls the actual files.
Dark-mode colours, when the admin sets them, are appended AFTER the compiled theme as a [data-bs-theme="dark"] block, so they always win the cascade.
Load the compiled CSS from meta.twig
Override the storefront's meta layout so the storefront links your per-channel compile, with a fallback to your static style.min.css for channels that have not saved branding yet.
{# resources/views/storefront/layouts/meta.twig #}
{% hw_extends 'storefront::layouts/meta.twig' %}
{# Your compile bundles its own Bootstrap - suppress the core one #}
{% block layouts_head_link_bootstrap %}{% endblock %}
{% block layouts_head_theme_css %}
{% set compiledThemeCss = salesChannel.getCompiledThemeCssUrl() %}
{% if compiledThemeCss %}
<link rel="stylesheet" href="{{ compiledThemeCss }}?v={{ hwCacheId }}">
{% else %}
<link rel="stylesheet" href="{{ asset('themes/hw/mytheme/css/style.min.css') }}?v={{ hwCacheId }}">
{% endif %}
{% endblock %}Ship a checked-in style.min.css with the theme so brand-new sales channels render correctly before the first admin save.
During development
Editing SCSS does not trigger a recompile on its own. The per-channel CSS only rebuilds when the admin hits Save on the branding tab, or when a command tells it to. Two helpers cover the common cases:
php artisan theme:watchpolls every SCSS file under every installed theme and recompiles the affected sales channels on change. Use it while iterating on styles. Optional flags:--interval=<seconds>for the polling cadence,--initialto run a full compile once on startup.$salesChannel->recompileBranding(force: true)from tinker or a post-update hook rebuilds fonts, Bootstrap and the theme in one go. Use it after a hostware update, since the updater overwrites/public/assets.
A compile failure on one sales channel leaves the previous file in place, so the storefront keeps rendering. Errors go to the artisan output and the Laravel log, not to the storefront.