Presets, design tokens and deploy for multiple storefronts
Multiple brands or country shops on the same Magento instance need different colors, fonts and sometimes even different layouts, yet want to share the same codebase. Clean Hyvä multi store theming with Tailwind CSS separates shared structure from store specific design tokens, instead of maintaining a full copy of the theme for every brand.
Table of Contents
- 1. Two basic models for multi store theming
- 2. Theme assignment per store view in Magento
- 3. A shared Tailwind preset as the base
- 4. Store specific design tokens through data attributes
- 5. When separate theme packages are needed
- 6. Accounting for RTL stores in multi store theming
- 7. Deploy pipeline for multiple themes
- 8. Common mistakes in multi store theming
- 9. Single build vs. separate themes compared
- 10. Summary
- 11. FAQ
1. Two basic models for multi store theming
Before starting the technical implementation, the fundamental question needs answering: do the storefronts only differ in colors, logo and font, or also structurally in layout and component behaviour? This decision determines whether Hyvä multi store theming runs on a single, token based Tailwind build or on multiple, fully separate theme packages per brand.
For pure color and brand variants, a single build with store specific CSS custom properties is the more efficient solution. For deep structural differences, for example a completely different category page structure for a B2B brand versus a B2C brand, a separate Hyvä theme per brand is the more robust path. The following sections cover both approaches to Hyvä multi store theming in detail, including the criteria for when each approach makes sense.
It matters to make this decision early in the project. Switching from a single build approach to separate theme packages later means significant migration effort, since every store specific override has to be restructured.
2. Theme assignment per store view in Magento
Magento allows assigning a theme per store view through Content > Design > Configuration in the backend, or declaratively through core_config_data with the path design/theme/theme_id, scoped to the respective store view. For Hyvä multi store theming it matters that this assignment works independently of whether one or several physical theme directories exist in the end, Magento only knows the theme ID, not the internal Tailwind structure behind it.
In a single build approach, multiple store views point to the same physical theme, but differ at runtime through a store identifier attribute on the layout's root element. With separate theme packages, every store view points to its own theme with its own theme.xml and its own Tailwind build. Both variants of Hyvä multi store theming are equally valid from Magento's perspective, but differ significantly in build and deploy effort.
3. A shared Tailwind preset as the base
For the single build approach, a shared Tailwind preset is the central foundation. A preset is a reusable base configuration that multiple theme configurations include through presets: [require(...)]. For Hyvä multi store theming this means: basic utility extensions, spacing scales and breakpoints are maintained centrally once, while every brand only overrides the design tokens that actually differ.
This approach significantly reduces redundancy, because structural changes, for example a new breakpoint definition, only need to happen once in the preset and automatically apply to every brand. For Hyvä multi store theming with more than two or three brands, this approach is nearly mandatory, otherwise inconsistencies between brands creep in gradually.
// web/tailwind/presets/shared-base.js — shared across all store brands
module.exports = {
theme: {
extend: {
spacing: {
18: '4.5rem',
22: '5.5rem'
},
borderRadius: {
card: '1rem'
}
}
}
};
// web/tailwind/tailwind.config.js — per-brand config extends the shared base
const sharedBase = require('./presets/shared-base.js');
module.exports = {
presets: [sharedBase],
content: ['../../**/*.phtml', '../../**/*.js'],
theme: {
extend: {
colors: {
// Brand-specific colors only, everything else inherited from preset
primary: '#0369a1'
}
}
}
};
4. Store specific design tokens through data attributes
Within a single build, store specific colors can be solved elegantly through CSS custom properties that take on different values depending on an attribute on the <html> or <body> element. Magento sets this attribute server side based on the current store code, so no additional JavaScript logic is needed. For Hyvä multi store theming this is the core of the single build strategy: one CSS file serves any number of brands.
The advantage over separate builds is build time: a single Tailwind compile pass covers every brand, instead of running a separate, time consuming build for each brand. The downside is that every brand loads the same CSS file, even if it only uses a fraction of the store specific rules, which can noticeably increase bundle size with a large number of brands.
/* web/tailwind/tailwind-source.css */
@import "tailwindcss";
@theme {
--color-primary: #0369a1;
}
/* Brand-specific token overrides, matched by a store code attribute
set server-side on the html element in the root template */
[data-store-code="brand-b2b"] {
--color-primary: #7c2d12;
}
[data-store-code="brand-outlet"] {
--color-primary: #166534;
}
<!-- app/design/frontend/Mironsoft/default/Magento_Theme/templates/root.phtml -->
<html lang="<?= $block->escapeHtmlAttr($this->helper(Locale::class)->getLocaleCode()) ?>"
data-store-code="<?= $block->escapeHtmlAttr($storeManager->getStore()->getCode()) ?>">
5. When separate theme packages are needed
Once brands differ not just in color but structurally, for example a completely different checkout order or a completely different category page layout, the single build approach hits its limits. Conditional templates with countless if (storeCode === 'brand-x') branches are harder to maintain than separate theme packages that each rely on the same Hyvä theme fallback to the same parent theme, but carry their own, precise overrides.
In this case every brand gets its own theme directory with its own theme.xml, its own Tailwind build, and its own preset reference to the same shared base configuration from section 3. For Hyvä multi store theming this means more build time and more deploy steps, but a much clearer separation of structural differences between brands, without templates being cluttered with store conditions.
6. Accounting for RTL stores in multi store theming
If one of the brands operates a store in a right to left written language, for example Arabic or Hebrew, Hyvä multi store theming additionally needs to account for writing direction. Tailwind CSS supports logical properties like ms-4 instead of ml-4, which automatically adapt to the writing direction set in the dir attribute, without needing separate RTL specific classes.
For multi store setups with mixed writing directions, it is crucial to consistently use logical instead of physical direction classes from the start, not as a retrofitted RTL patch. If this principle is followed when initially building the Hyvä multi store theming setup, a store added later with RTL works without structural CSS changes, only the dir="rtl" attribute needs to be set correctly server side.
7. Deploy pipeline for multiple themes
With separate theme packages, the deploy pipeline has to run its own build and deploy step for every theme. For Hyvä multi store theming with multiple brands, this means looping over every theme directory, each with its own npm run build and its own setup:static-content:deploy -t call. If a theme is forgotten in this loop, the affected brand stays on an outdated CSS state, without the mistake being immediately obvious.
With a single build approach, the pipeline is simpler, since only one build and deploy step runs for all brands together. For Hyvä multi store theming it is therefore worth documenting the deploy order and the list of themes to build explicitly in a script, instead of leaving it in the memory of individual team members.
#!/usr/bin/env bash
# deploy-multi-store-themes.sh — build and deploy every brand theme
set -euo pipefail
THEMES=(
"Mironsoft/default"
"Mironsoft/brand-b2b"
"Mironsoft/brand-outlet"
)
for theme in "${THEMES[@]}"; do
echo "[BUILD] ${theme}"
bin/npm --prefix "app/design/frontend/${theme}/web/tailwind" run build
echo "[DEPLOY] ${theme}"
bin/magento setup:static-content:deploy de_DE -t "${theme}" -f
done
bin/magento cache:flush
8. Common mistakes in multi store theming
The most common mistake in the single build approach is forgetting a store specific override in the CSS file, which causes a new brand to silently inherit another brand's default colors. For Hyvä multi store theming an automated check helps here, one that expects a matching CSS rule for every configured store code and triggers a build failure when one is missing, instead of only noticing the mistake in production.
With separate theme packages, the most common mistake is forgetting a theme in the deploy loop from section 7, or a stale preset reference when the shared base configuration changed but a brand theme was not rebuilt. A third mistake concerns RTL stores: if physical instead of logical direction classes are used, every affected template has to be manually retrofitted for RTL, which significantly increases the maintenance burden of Hyvä multi store theming.
9. Single build vs. separate themes compared
The choice between a shared build and separate theme packages depends on the degree of structural difference between brands. The table below summarizes the key differences for Hyvä multi store theming.
| Criterion | Single build with tokens | Separate theme packages |
|---|---|---|
| Only colors and logo differ | Very well suited | Unnecessary overhead |
| Different layout per brand | Leads to store conditions in templates | Cleaner via theme fallback |
| Build time with many brands | One build for all brands | One build per brand |
| CSS bundle size | Contains all brand overrides | Only its own brand per bundle |
Mironsoft
Hyvä theme architecture for multi store and multi brand setups
Multiple brands, one maintainable theme architecture?
We design and implement Hyvä multi store theming for your brands, with a shared preset base, clean token separation and a reliable deploy pipeline for every storefront.
Architecture consulting
Evaluating single build vs. separate themes based on your brand structure
Preset setup
Building a shared Tailwind base configuration for all brands
Deploy automation
Script based build and deploy pipeline for multiple theme packages
10. Summary
Successful Hyvä multi store theming starts with the early decision of whether brands differ only in color or also structurally. For pure color and brand variants, a single build with a shared Tailwind preset and store specific CSS custom properties through data-store-code delivers the most efficient solution, with a single build pass covering every brand. For structural differences, separate theme packages that rely on theme fallback to the same parent base are the more maintainable choice.
Regardless of the chosen model, a documented deploy pipeline, consistently logical direction classes for RTL readiness, and an automated check for missing store overrides secure the long term success of Hyvä multi store theming projects, even as more brands get added over time.
Hyvä Multi Store Theming — The Essentials at a Glance
Basic decision
Color differences: single build with tokens. Structural differences: separate theme packages.
Shared preset
Maintain spacing, breakpoints and utility extensions centrally, override only colors per brand.
Store specific tokens
data-store-code attribute combined with CSS custom properties, set server side without JavaScript.
Deploy pipeline
With separate themes: a documented loop over every theme directory, no theme forgotten.