Skip to main content
Version: 2.0.0

Registering a Custom Theme

If you want full control over cart and checkout visual styles — your own design system, no inheritance from a built-in theme — you can register a named custom theme. Once registered, it appears in the yStore plugin settings panel alongside the built-in themes (Modern, Bold, Minimal, etc.) and can be activated without touching code.

This is the right approach for agencies or developers shipping a reusable theme package.

How it works

Custom themes are registered by listening to ThemeService::EVENT_REGISTER_THEMES from a Craft module and adding an entry to $event->themes. The plugin will include your CSS files instead of its own when that theme is active.

Step 1 — Build your CSS files

Create two CSS files: one for the cart, one for checkout. You can start from the plugin's default variables and build from there, or write from scratch.

A minimal starting point that only overrides variables:

/* web/assets/my-theme/cart.css */

:root {
--cart-font-family: 'Poppins', sans-serif;
--cart-border-radius: 12px;
--cart-item-border-radius: 8px;
--cart-border-color: #e2e8f0;
--cart-background-color: #ffffff;
--cart-text-color: #1a202c;

--cart-submit-button-background-color: #6366f1;
--cart-submit-button-hover-background-color: #4f46e5;
--cart-submit-button-text-color: #ffffff;
--cart-submit-button-height: 52px;

--cart-remove-button-background-color: #f43f5e;
--cart-remove-button-hover-background-color: #e11d48;
--cart-remove-button-border-radius: 6px;

--cart-summary-background-color: #f8fafc;
--cart-totals-border-color: #e2e8f0;

--cart-coupon-button-background-color: #0ea5e9;
--cart-coupon-button-text-color: #ffffff;
--cart-coupon-button-hover-background-color: #0284c7;
}
/* web/assets/my-theme/checkout.css */

:root {
--checkout-font-family: 'Poppins', sans-serif;
--checkout-heading-font-size: 26px;
--checkout-heading-font-weight: 700;
--checkout-border-radius: 16px;
--checkout-input-border-radius: 8px;
--checkout-border-color: #e2e8f0;
--checkout-text-color: #1a202c;

--checkout-submit-button-background-color: #6366f1;
--checkout-submit-button-hover-background-color: #4f46e5;
--checkout-submit-button-text-color: #ffffff;
--checkout-submit-button-height: 52px;

--checkout-input-border-color: #cbd5e1;
--checkout-input-height: 44px;
--checkout-input-font-size: 15px;

--checkout-card-background-color: #ffffff;
--checkout-card-shadow: 0 4px 24px rgba(99,102,241,.08);

--checkout-method-selection-background-color: #ede9fe;
--checkout-method-selection-border-color: #c4b5fd;
}
You only need to set what you want to change

The plugin's default variable values are still declared in its own stylesheet. Your file only needs the properties you are overriding.

Step 2 — Register the theme in your module

use yui\craft\services\ThemeService;
use yui\craft\events\RegisterThemeEvent;
use yui\craft\support\EventManager;

class MyModule extends \craft\base\Module
{
public function init(): void
{
parent::init();

EventManager::listen(
ThemeService::class,
ThemeService::EVENT_REGISTER_THEMES,
function (RegisterThemeEvent $event) {
$event->themes['my-brand'] = [
'label' => 'My Brand',
'description' => 'Indigo & slate design system',
'cartCss' => '@webroot/assets/my-theme/cart.css',
'checkoutCss' => '@webroot/assets/my-theme/checkout.css',
];
}
);
}
}

Theme definition keys

KeyRequiredDescription
labelYesDisplay name shown in the settings dropdown
descriptionYesShort description shown below the label
cartCssYesPath to your cart stylesheet (Craft alias or absolute URL)
checkoutCssYesPath to your checkout stylesheet
layoutRequirementsNoCustom layout/template overrides — see below

Step 3 — Activate in plugin settings

Go to Settings → yStore → Storefront and select your theme name from the Cart Theme and Checkout Theme dropdowns. Save. The plugin will use your CSS files from the next page load onward.

Layout requirements (advanced)

Some themes require a specific Twig layout or page template — for example, a full-page checkout that stretches to the viewport edges. You can declare this alongside the CSS registration:

$event->themes['my-brand'] = [
'label' => 'My Brand',
'description' => 'Full-page checkout variant',
'cartCss' => '@webroot/assets/my-theme/cart.css',
'checkoutCss' => '@webroot/assets/my-theme/checkout.css',
'layoutRequirements' => [
'cart' => 'yui/layouts/cart/1column.twig',
'cartPageTemplate' => 'yui/pages/cart/view.twig',
'checkout' => 'yui/layouts/checkout/fullpage.twig',
'checkoutPageTemplate' => 'yui/pages/checkout/view.twig',
],
];

When layout requirements are set, ThemeService::getThemeLayout() and getThemePageTemplate() return your specified templates instead of the defaults, so the HTML structure matches your CSS.

Combining a custom theme with a theme override

You can still use themeOverrides on your own custom theme key to inject a second CSS file after the main one:

$event->themes['my-brand'] = [ /* ... */ ];

// loaded after my-brand's main CSS
$event->themeOverrides['my-brand'] = [
'cartCss' => '@webroot/assets/my-theme/cart-dark-mode.css',
];

Packaging a custom theme as a Craft plugin

If you are distributing a theme as a standalone plugin, register the event listener in your plugin's init() instead of a module. The $event->themes array is shared across all listeners, so multiple plugins can each register their own themes simultaneously.