Design tokens en Tailwind in Hyvä: config, branding en Figma-koppeling

Kleuren, spacing en typografie op één plek, zodat Figma en code dezelfde taal spreken. Zo richt je design tokens in voor Hyvä met Tailwind v4 of v3, tune je de config en bouw je een merk-eigen theme op Hyvä UI.

Coding.nl
Bijgewerkt 12 leestijd
Inhoud van dit artikel
  1. Wat zijn design tokens?
  2. Hoe Hyvä met tokens omgaat
  3. Tokens uit Figma halen
  4. Welke tokens pak je als eerste aan?
  5. De Tailwind-config scherp houden
  6. Een merk-eigen theme bouwen op Hyvä UI
  7. Tokens automatisch bijhouden
  8. Wanneer deze aanpak niet past
  9. Samengevat

Drie Figma-bestanden, een stylesheet die niemand durft aan te raken en vier tinten "primair blauw" in productie. Zo ziet een project zonder design tokens eruit. In een Hyvä-theme met Hyvä UI los je dat op door kleuren, spacing en typografie op één plek vast te leggen en die plek te koppelen aan Figma. Dit artikel laat zien hoe dat werkt in Hyvä 1.4 en nieuwer (Tailwind v4) en in oudere themes (Tailwind v3), hoe je de Tailwind-config scherp houdt en hoe je er een merk-eigen theme op bouwt.

Wat zijn design tokens?

Design tokens zijn benoemde ontwerpbeslissingen met een concrete waarde:

  • color-primary: #1D4ED8
  • spacing-md: 1.5rem
  • font-size-heading: 2.25rem

In Figma leven ze als styles of variabelen, in code in je theme-configuratie. Zonder koppeling leven ze twee keer en lopen ze vroeg of laat uit de pas. Met koppeling heb je één bron van waarheid.

Tokens in lagen

Volwassen design systems werken met lagen:

  1. Primitieven: ruwe waarden zonder context, zoals blue-700: #1D4ED8 of space-6: 1.5rem.
  2. Semantische tokens: betekenis bovenop primitieven, zoals color-primary: {blue-700}, color-danger of color-surface.
  3. Component-tokens (optioneel): waarden per component, zoals button-padding-x of input-border-color.

Configureer in je theme bij voorkeur de semantische laag. Dan wissel je een merkkleur of een donker thema zonder classes in templates te herschrijven.

Hoe Hyvä met tokens omgaat

Hyvä 1.4 en nieuwer: Tailwind v4

Sinds Hyvä 1.4.0 ondersteunt Hyvä Tailwind CSS v4. De configuratie verhuist daarmee van tailwind.config.js naar CSS, via het @theme-blok. Voor tokens introduceert Hyvä een eigen bestand: web/tailwind/hyva.config.json, aan te maken met npx hyva-init.

Het eenvoudigste is tokens direct in dat bestand te zetten:

json
{
  "tokens": {
    "values": {
      "color": {
        "primary": {
          "lighter": "oklch(62.3% 0.214 259.815)",
          "DEFAULT": "oklch(54.6% 0.245 262.881)",
          "darker": "oklch(37.9% 0.146 265.522)"
        }
      },
      "spacing": {
        "xs": "0.5rem",
        "sm": "0.75rem",
        "md": "1rem",
        "lg": "1.5rem",
        "xl": "2rem"
      }
    }
  }
}

npx hyva-tokens zet dit om naar CSS-variabelen in generated/hyva-tokens.css:

css
@theme {
    --color-primary: oklch(54.6% 0.245 262.881);
    --spacing-xs: 0.5rem;
}

Tailwind v4 maakt van zo'n --color-<em>-variabele automatisch utilities als bg-primary en text-primary. De entry van je theme, tailwind-source.css, importeert dat gegenereerde bestand samen met de rest. Vereenvoudigd:

css
@import "tailwindcss" source(none);
@source "../../**/*.phtml";
@source "../../**/*.xml";

@import "./generated/hyva-source.css";
@import "./generated/hyva-tokens.css";
@import "./base";
@import "./components";
@import "./theme";
@import "./utilities";

In de package.json van het theme draaien hyva-sources en hyva-tokens vóór elke build:

json
{
  "scripts": {
    "generate": "npx hyva-sources && npx hyva-tokens",
    "prebuild": "npm run generate",
    "build": "npx tailwindcss -i tailwind-source.css -o ../css/styles.css --minify",
    "prewatch": "npm run generate",
    "watch": "npx tailwindcss -i tailwind-source.css -o ../css/styles.css --watch"
  }
}

Let op twee details uit de upgrade-documentatie: in CSS-imports is het ./-prefix verplicht, en Tailwind v4 vraagt moderne browsers (Safari 16.4+, Chrome 111+, Firefox 128+). Node 20 of hoger wordt aanbevolen.

Ook donkere varianten kun je als token vastleggen. Een waarde met de sleutel @media:dark-background belandt in een eigen @theme-blok binnen @media (prefers-color-scheme: dark).

Oudere themes: Tailwind v3

Draai je nog een theme op Tailwind v3, dan staan tokens in theme.extend van tailwind.config.js. Hyvä documenteert ook een tussenweg: hyva.config.json inlezen in je Tailwind v3-config, zodat je alvast één bron hebt voor je later overstapt:

js
// web/tailwind/tailwind.config.js (Tailwind v3)
const hyvaConfig = require('./hyva.config.json');

module.exports = {
  theme: {
    extend: {
      colors: hyvaConfig.tokens.values.color,
    },
  },
};

Tokens uit Figma halen

De koppeling met Figma loopt in Hyvä via een JSON-export. De documentatie gaat uit van Tokens Studio, een plugin voor Figma en Penpot. Er zijn twee formaten:

  • DTCG (standaard in huidige versies van Tokens Studio): sleutels met een $-prefix, zoals $value en $type. Geen extra instelling nodig.
  • Legacy: sleutels zonder prefix (value, type). Zet dan "format": "figma".

Een legacy-export ziet er zo uit:

json
{
  "color": {
    "primary": { "value": "#1D4ED8", "type": "color" },
    "primary-dark": { "value": "#1E3A8A", "type": "color" },
    "surface": { "value": "#F9FAFB", "type": "color" }
  },
  "spacing": {
    "sm": { "value": "1rem", "type": "spacing" },
    "md": { "value": "1.5rem", "type": "spacing" }
  }
}

Verwijs er in hyva.config.json naar met src:

json
{
  "tokens": {
    "src": "acme.tokens.json",
    "format": "figma"
  }
}

Een paar valkuilen uit de praktijk en de documentatie:

  • Wrapper-groepen komen in de variabelenaam. Staat alles onder een groep core, dan krijg je --core-primary in plaats van --color-primary. Haal zulke groepen weg vóór de conversie.
  • Verwijzingen moeten in hetzelfde bestand staan. {spacing.sm} wordt var(--spacing-sm); bestaat dat token niet, dan breekt de stijl.
  • Controleer de gegenereerde namen. De tool probeert type-groepen zoals color uit namen te strippen; bij sommige exports gaat dat mis. Hyvä heeft aangekondigd dit gedrag expliciet opt-in te maken, dus kijk na een update van de tooling of je namen nog kloppen.

Hyvä ondersteunt naast Tokens Studio ook exports uit onder meer Google Stitch en standaard DTCG-JSON. Welke tool je ook gebruikt: kijk na elke export in generated/hyva-tokens.css of de variabelen heten wat je verwacht.

Welke tokens pak je als eerste aan?

Begin niet met alles tegelijk:

Token-categorieWaarom nu?
Kleuren (merk, surface, feedback)Meest zichtbaar, vaakst fout
Spacing-schaalConsistente layout, minder afwijkende componenten
Typografie (groottes, gewichten)Direct zichtbaar, raakt leesbaarheid
Border-radiusKlein verschil, groot effect op merkbeleving
ShadowsLaagste prioriteit, maar snel geregeld

Kleuren en spacing geven in de eerste sprint al zichtbaar resultaat.

De Tailwind-config scherp houden

Tokens zijn de helft van het verhaal. De andere helft is zorgen dat Tailwind precies de CSS genereert die je gebruikt, niet meer en niet minder.

Content-paden: de meest gemaakte fout

Tailwind scant bestanden op classnamen. Mis je een pad, dan ontbreken classes in productie en zie je een knop zonder styling terwijl de classes gewoon in de HTML staan. Scan je te breed, dan wordt je CSS groter en de build trager.

In Tailwind v4 zet je de scan met @source en schakel je automatische detectie uit met source(none), zoals in het voorbeeld hierboven. Classes uit Hyvä-compatibele modules haalt npx hyva-sources binnen in generated/hyva-source.css; welke modules meedoen, stuur je met de tailwind.include- en exclude-arrays in hyva.config.json.

In Tailwind v3 doe je hetzelfde in de content-array van tailwind.config.js:

js
module.exports = {
  content: [
    '../templates/**/*.phtml',
    '../../**/*.phtml',
    '../../**/layout/*.xml',
  ],
};

Drie regels die altijd gelden:

  • Scan nooit de hele Hyvä UI-bibliotheek. Je kopieert losse componenten naar je theme; alleen die kopieën horen in de scan. Anders genereert Tailwind classes voor componenten die je niet gebruikt.
  • Scan nooit node_modules. Dat vertraagt de build en levert vrijwel nooit nuttige classes op.
  • Layout XML telt mee. Classes die via layout XML worden gezet, moeten gevonden worden.

Uitbreiden, niet overschrijven

In Tailwind v3 is de klassieke fout theme.colors direct instellen in plaats van theme.extend.colors. Dan gooit Tailwind het standaardpalet weg, inclusief classes die Hyvä-templates en Hyvä UI-componenten zelf gebruiken. Gebruik in een Hyvä-theme dus extend:

js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: { DEFAULT: '#1a56db', dark: '#1e429f', light: '#ebf5ff' },
        secondary: { DEFAULT: '#0e9f6e', dark: '#057a55' },
      },
      fontFamily: { sans: ['Inter', 'ui-sans-serif', 'system-ui'] },
      borderRadius: { btn: '0.375rem' },
      spacing: { header: '4rem' },
    },
  },
};

Wil je het standaardpalet bewust beperken om afwijkende kleuren te voorkomen, doe dat dan pas als je hebt gecontroleerd welke standaardclasses je templates gebruiken. In Tailwind v4 geldt hetzelfde principe: tokens voegen variabelen toe aan het @theme-blok; het standaardpalet resetten met --color-</em>: initial is een bewuste keuze, geen default.

Plugins

In Tailwind v3-themes gebruik je @tailwindcss/forms bijna altijd: zonder die plugin zien select, input en textarea er per browser anders uit. Met strategy: 'class' stijl je alleen elementen met classes als form-input en form-select, handig als je theme eigen form-stijlen heeft:

js
const forms = require('@tailwindcss/forms');

module.exports = {
  plugins: [forms({ strategy: 'class' })],
};

@tailwindcss/typography heeft alleen zin voor rijke CMS-tekst; gebruik de prose-classes dan gericht op die blokken.

Bij de upgrade naar Hyvä 1.4 met Tailwind v4 verwijder je deze twee plugins en PostCSS uit je theme; Hyvä levert de forms- en typography-functionaliteit dan via @hyva-themes/hyva-modules.

Safelist voor dynamische classes

Classes die alleen dynamisch ontstaan, kan Tailwind niet vinden. De beste oplossing is ze voluit in de template te schrijven. Lukt dat niet, gebruik dan een safelist.

Tailwind v3:

js
module.exports = {
  safelist: ['opacity-0', 'opacity-100', 'translate-x-full', '-translate-x-full'],
};

Tailwind v4.1 en nieuwer:

css
@source inline("opacity-0 opacity-100 translate-x-full -translate-x-full");

Houd de safelist klein. Een brede safelist doet de winst van de scan teniet.

Geen @layer components voor alles

Het is verleidelijk om componenten te overschrijven met eigen CSS in @layer components. Dat werkt, maar levert specificiteitsproblemen op en verstopt stijl op een plek waar niemand zoekt. Leg tokens vast in de theme-config en los afwijkingen op met utility-classes in de template.

Een merk-eigen theme bouwen op Hyvä UI

Met tokens op orde wordt branding grotendeels configuratie. Dat is vooral interessant voor bureaus die meerdere winkels bouwen en voor merchants met een uitgesproken huisstijl.

De white-label-aanpak: één basis, meerdere merken

Zonder gedeelde basis bouw je voor vijf winkels vijf keer een button, een modal en een accordion, en onderhoud je dat vijf keer. Met Hyvä UI als basis heb je één set componenten en pas je per winkel de tokens aan. Elke winkel ziet er anders uit, de code is grotendeels gelijk. Houd er rekening mee dat de Hyvä UI-licentie per Magento-installatie geldt: vijf winkels op vijf installaties zijn vijf licenties.

Drie stappen voor de basis

  1. Kleuren: merkkleur als primary, plus secondary en accent.
  2. Typografie: je webfont koppelen, eventueel met een apart display-font voor koppen.
  3. Spacing en border-radius: één schaal, consistent door alle componenten.

Een merkspecifieke tokenset in hyva.config.json:

json
{
  "tokens": {
    "values": {
      "color": {
        "primary": { "lighter": "#2D5F8A", "DEFAULT": "#1A3C5E", "darker": "#0F2337" },
        "accent": { "DEFAULT": "#E8500A" }
      },
      "spacing": {
        "section": "5rem"
      }
    }
  }
}

Fonts zet je in Tailwind v4 in het @theme-blok van je theme-CSS:

css
@theme {
    --font-sans: "Geist", ui-sans-serif, system-ui;
    --font-display: "Playfair Display", Georgia, serif;
    --radius-lg: 0.5rem;
}

Gebruikt je button bg-primary, je card rounded-lg en je kop font-display, dan verandert alles mee zonder zoeken en vervangen in templates.

Wanneer tokens niet genoeg zijn

Soms wil een merk meer dan andere kleuren: een eigen hover-animatie, of een product card met een andere informatievolgorde. Dan pas je de template aan, niet de JavaScript. Door de HTML-first-opzet staat de Alpine-interactie los van de visuele structuur.

AanpassingAanpakBereik
MerkkleurTokenGlobaal
LettertypeToken / @themeGlobaal
Button-vormToken (border-radius)Globaal
Button hover-animatieClasses in de templateAlleen dat component
Product card-layoutTemplate aanpassenAlleen dat component
Modal-gedragAlpine-logica aanpassenAlleen dat component

De vuistregel: ga zo globaal mogelijk. Alles wat je op tokenniveau regelt, scheelt onderhoud per component. Hoe je een eigen component bouwt als er niets bestaat, staat in custom componenten bouwen met Hyvä UI.

Blijft de performance intact?

Ja, zolang je de kern respecteert. Tailwind genereert alleen classes die in je bestanden voorkomen, dus extra tokens maken je CSS niet groter zolang je ze niet gebruikt. Wat wel kost: zware JavaScript-libraries toevoegen voor effecten die ook in CSS kunnen, of een brede safelist. Meet na elke grote stijlwijziging je Core Web Vitals.

Zo ziet een branding-traject er bij ons uit

  1. Inventarisatie huisstijl: kleurpalet, typografie, spacing, merkgids.
  2. Token-mapping: huisstijl vertalen naar tokens, inclusief donkere varianten als die nodig zijn.
  3. Figma bijwerken: de styles in het Hyvä UI Figma-bestand aanpassen, zodat ontwerp en code gelijk lopen.
  4. Component-audit: welke componenten passen direct, welke vragen template-aanpassingen?
  5. Build-controle: geen ontbrekende of dubbele CSS, metingen op productie.
  6. Documentatie: een korte gids voor het team of de klant over het toevoegen van een nieuw token.

Tokens automatisch bijhouden

Handmatig exporteren werkt, maar zonder vaste route loopt het uit de pas. Twee niveaus:

Halfautomatisch (genoeg voor de meeste teams):

  1. De designer exporteert de token-JSON met Tokens Studio.
  2. Het bestand gaat in de repository, op het pad uit tokens.src.
  3. npm run build draait hyva-tokens automatisch mee.
  4. De diff in generated/hyva-tokens.css wordt gereviewd als gewone code.

Volledig automatisch: Tokens Studio kan (in de betaalde versie) tokens synchroniseren met een Git-repository. Een CI-job bouwt het theme bij elke wijziging en zet de diff in een pull request. Kost wat inrichting, maar daarna is er geen handwerk meer.

In beide gevallen geldt: tokens zijn code. Ze gaan via review, niet rechtstreeks naar productie.

Wanneer deze aanpak niet past

  • Je gebruikt geen Tailwind. Tokens kun je overal gebruiken, maar de Hyvä-tooling en Hyvä UI zijn gebouwd op Tailwind.
  • Je hebt al een volwassen design system. Dan koppel je dat aan je theme, in plaats van een tweede systeem in te voeren.
  • Er is geen Figma-workflow. Tokens in code blijven nuttig, maar een groot deel van de winst zit in de koppeling met het ontwerp.
  • Je verwacht van Hyvä UI een compleet theme. Hyvä UI is een componentbibliotheek bovenop een Hyvä theme, geen vervanging.
  • Je project staat vlak voor livegang. Een token-refactor op dat moment is risicovol. Plan het in een volgende fase.

Samengevat

  1. Leg tokens vast op één plek: hyva.config.json in Hyvä 1.4+, theme.extend in oudere themes.
  2. Haal ze uit Figma via een JSON-export en laat hyva-tokens het omzetten.
  3. Scan alleen wat je gebruikt, breid uit in plaats van te overschrijven en houd plugins en safelist klein.
  4. Doe branding zoveel mogelijk op tokenniveau, pas templates alleen aan waar het moet.

Dan gaan reviews over functionaliteit, niet over de vraag of dit nu de goede tint blauw is. Meer over het Figma-bestand van Hyvä UI lees je in Hyvä UI als design system in Figma.


Wil je weten of je huidige theme-setup klaar is voor deze aanpak? Wij doen een gratis Tech Check: we kijken naar je Tailwind-config, je tokens, je Figma-workflow en je build, en geven concrete aanbevelingen. Neem contact op via /contact. Geen verkoopgesprek, geen rapport van dertig pagina's.

Ruthger Idema

Geschreven door Ruthger Idema

Eigenaar van Coding.nl. 15+ jaar e-commerce met Magento, Shopify en Laravel, samen met het vaste team in Emmen.

Wil je dit voor jouw shop laten uitzoeken? Plan een half uur

Een half uur via video met de mensen die het werk ook echt doen. Kies hieronder een moment dat jou past.

  • Direct met het vaste team, geen tussenlagen
  • Concrete feedback op je huidige situatie of plannen
  • Eerlijk advies, ook als het antwoord "niet doen" is
  • Indicatie van kosten en tijdlijn
Liever bellen? 0591-239 299
Beschikbaar deze week

Plan een gratis Tech Check

Vrijblijvend jouw uitdagingen bespreken

Of bel direct: 0591-239 299