Een Magento 2-ecommerce opschalen naar 15 winkels en 9 talen vanuit een enkele installatie is geen theoretisch scenario. Het is een project dat we daadwerkelijk hebben uitgevoerd voor Loviux, een ecommerce voor intiem welzijn die actief is in heel Europa. Dit artikel documenteert de technische keuzes, de knelpunten die we tegenkwamen en hoe we die hebben opgelost.
Als je met Magento op schaal werkt — als CTO, tech lead of senior developer — vind je hier wat we leerden bij de migratie van Luma naar Hyva, het bouwen van een custom checkout zonder zware frameworks, het automatiseren van contentgeneratie voor meer dan 9.000 producten en het onderhouden van een performancestack die niet omvalt bij deployment.
Waarom migreren van Luma naar Hyva (en wat het werkelijk oplevert)
Luma was jarenlang de standaard frontend van Magento 2. En jarenlang was het ook de grootste technische last.
De werkelijke kosten van Luma
De Luma-stack is gebaseerd op RequireJS voor het laden van modules en Knockout.js voor data binding. Beide zijn technologieen uit 2013 die Magento heeft overgenomen en nooit heeft gemoderniseerd. Het praktische resultaat bij een project met 15 winkels:
- RequireJS veroorzaakt een waterval van HTTP-verzoeken die de rendering blokkeren. Bij een catalogus met duizenden producten laadde elke pagina tussen de 40 en 60 JS-bestanden voordat deze interactief was.
- Knockout.js voegt gewicht toe zonder meerwaarde. Voor een ecommerce waar de echte interactiviteit beperkt is tot winkelwagen, filters en checkout, is een volledig data-binding-framework overdreven.
- De CSS van Luma weegt ~300 KB ongecomprimeerd. Elke aanpassing voegt lagen LESS toe die niemand durft te refactoren.
In onze tests had een categoriepagina in Luma een LCP (Largest Contentful Paint) van 4,2 seconden op mobiel. Onacceptabel voor een webshop waar elke extra seconde laadtijd de conversie met 7% verlaagt volgens gegevens van Google.
Wat we winnen met Hyva + Tailwind CSS
Hyva vervangt de complete Luma-frontend door een moderne architectuur: Alpine.js voor interactiviteit, Tailwind CSS voor styling en nul legacy-afhankelijkheden.
De cijfers na de migratie:
Dit is geen incrementele verbetering. Het is een verschil van een orde van grootte. En bij een multi-store met 15 winkels vermenigvuldigt dat verschil zich: minder serverbronnen per request, betere cache, betere ervaring in elk van de 9 talen.
De migratie was niet triviaal. Elke module van derden die Luma gebruikte (en dat waren er meer dan 30) had een compatibility module voor Hyva of een volledige vervanging nodig. We documenteerden elke afhankelijkheid vooraf en prioriteerden op basis van zakelijke impact. Modules die alleen het admin-panel betroffen, hoefden niet aangepast te worden; modules met frontend .phtml-templates wel.
Multi-store op schaal: 15 winkels, 9 talen, een installatie
Magento ondersteunt multi-store van nature, maar de realiteit van beheer op schaal is een ander verhaal.
Architectuur van websites, stores en store views
De opzet van Loviux heeft 3 niveaus:
- Websites: groeperen winkels op basis van prijszones en belastingregels (Zuid-EU, Noord-EU, VK)
- Stores: een per land (Spanje, Frankrijk, Duitsland, Italie, Nederland, Portugal, Polen, Oostenrijk, Zwitserland, Belgie, Verenigd Koninkrijk, plus varianten)
- Store views: de taallaag. Een store kan meerdere views hebben (Zwitserland heeft er 3: DE, FR, IT; Belgie heeft er 2: NL, FR)
In totaal 15 store views die content serveren in 9 talen: Spaans, Engels, Portugees, Frans, Duits, Italiaans, Nederlands, Pools en de regionale varianten.
Custom taal-fallbacksysteem
Hier stuitten we op de eerste echte uitdaging. Magento heeft een eenvoudig fallbackmechanisme voor vertalingen, maar dat lost het probleem van cataloguscontent niet op.
Het probleem: wanneer een product geen vertaalde beschrijving heeft voor Oostenrijks Duits (de_AT), toont Magento een leeg veld. Het valt niet automatisch terug op standaard Duits (de_DE). Dat betekent dat je zonder fallbacksysteem elk product afzonderlijk moet vertalen voor elke locale, inclusief varianten die dezelfde taal delen.
Onze oplossing: we bouwden een plugin die het laden van gelokaliseerde attributen onderschept en een configureerbare fallbackketen toepast:
Het resultaat: landvarianten erven automatisch de content van de hoofdtaal. Je hoeft slechts een keer per taal te vertalen, en regionale verschillen (prijzen, beschikbaarheid, juridische teksten) worden op store-niveau beheerd zonder de volledige catalogus te dupliceren.
Dit mechanisme reduceerde de vertaalinspanning met 65% en elimineerde het risico van duizenden producten met lege velden in secundaire winkels.
Custom checkout met Magewire en Alpine.js
De checkout is waar een webshop geld verdient of verliest. De standaard Magento 2-checkout (gebaseerd op Knockout.js + UI Components) is functioneel maar zwaar, traag en lastig aan te passen.
Waarom we React en Knockout afwezen
We evalueerden drie opties:
- Luma stock checkout: afgewezen omdat we naar Hyva migreerden en het behouden van Knockout alleen voor de checkout inconsistent was.
- Checkout met React (zoals Hyva Checkout): voegt een extra afhankelijkheid van ~130 KB toe plus een apart build-pipeline. Voor een formulier van 3 stappen is dat buitenproportioneel.
- Magewire + Alpine.js: dezelfde stack als de rest van Hyva. Geen extra afhankelijkheden, geen apart build-pipeline, geen state-conflicten tussen frameworks.
We kozen Magewire. Het is een port van Laravel Livewire voor Magento waarmee je interactieve componenten bouwt met PHP op de server en Alpine.js op de client. Het resultaat is een checkout die minder dan 15 KB JS weegt (zonder Alpine mee te rekenen, dat al globaal geladen is).
3-koloms layout
We ontwierpen de checkout in een 3-koloms layout op desktop:
- Linkerkolom: verzendadres en klantgegevens
- Middenkolom: verzend- en betaalmethoden
- Rechterkolom: orderoverzicht, kortingscodes, totalen
De drie panelen worden server-side gerenderd met Magewire en bijgewerkt via AJAX wanneer de gebruiker gegevens wijzigt. Geen SPA, geen client-side router, geen gedeelde state tussen frameworks. Elk Magewire-component is onafhankelijk en communiceert rechtstreeks met de backend.
Op mobiel klappen de kolommen in tot een verticale flow met accordeons. Dezelfde code, zonder duplicatie of ingewikkelde layout-mediaquery's.
Resultaat: de checkout laadt in 1,1 seconde op mobiel (LCP) en het abandonpercentage bij de betaalstap daalde met 12% ten opzichte van de vorige Luma-checkout.
Catalogus van 60.000+ producten met geavanceerd zoeken
Een catalogus van deze omvang heeft meer nodig dan de standaardzoekopdracht van Magento (MySQL FULLTEXT). Er is snelle, relevante faceted search nodig.
SmileElasticSuite met OpenSearch
We implementeerden SmileElasticSuite, de meest volwassen open-source zoekoplossing voor Magento, gekoppeld aan OpenSearch 2.x als indexatieengine.
Belangrijke configuratie:
- Faceted search met dynamische filters per categorie: de beschikbare filters wijzigen op basis van de huidige categorie (maat, kleur, materiaal, merk, prijsklasse)
- Autocomplete met suggesties voor producten, categorieen en zoektermen
- Synoniemen per taal: geconfigureerd per store view, zodat "glijmiddel" en "intiem glijmiddel" dezelfde resultaten opleveren
- Aangepaste relevantie: boost voor producten met voorraad, met afbeelding en met reviews boven de rest
De volledige herindexering van de catalogus (60.000+ producten x 9 talen) duurt 8 minuten met een dedicated cron. Incrementele updates (prijs, voorraad) worden in minder dan 30 seconden verwerkt.
Voorraadsynchronisatie met leveranciers
Loviux werkt met meerdere leveranciers die voorraadfeeds aanleveren in uiteenlopende formaten: XML, CSV en in een geval een custom JSON-endpoint.
We bouwden een modulair importsysteem:
- Parsers per leverancier: elke leverancier heeft een adapter die de feed normaliseert naar het interne formaat (SKU, aantal, kostprijs, levertijd)
- Dagelijkse geplande uitvoering: een Magento-cron voert de synchronisatie elke nacht uit om 3:00 uur (het rustigste moment qua verkeer)
- Logging en meldingen: als een leverancier geen feed levert of het formaat wijzigt, wordt het team per e-mail op de hoogte gesteld
- Geaggregeerde voorraad: voor dropship-producten is de zichtbare voorraad de som van alle leveranciers die het product leveren
Dit systeem verwerkt ~15.000 voorraadregel per nacht zonder impact op de frontend-performance.
AI-pipeline voor content: 9.000 producten in 9 talen
Dit is misschien wel de meest interessante uitdaging van het project. Met meer dan 9.000 producten die een beschrijving nodig hebben in 9 talen, spreken we over 81.000 productteksten. Dat handmatig doen is noch financieel noch qua tijd haalbaar.
De pipeline in 4 stappen
We ontwierpen een geautomatiseerde pipeline met GPT-4o-mini (gekozen vanwege de verhouding kosten/kwaliteit bij massale generatie):
Stap 1 — Feature-extractie: we lezen de technische fiches van de fabrikant (naam, ingredienten, volume, producttype, bijzondere kenmerken) en structureren deze in een genormaliseerd JSON-formaat.
Stap 2 — Native generatie per taal: in plaats van in het Spaans te genereren en te vertalen, genereren we rechtstreeks in elke doeltaal. Het verschil is merkbaar: een tekst die native in het Nederlands is gegenereerd klinkt natuurlijk; een vertaling uit het Spaans klinkt als een vertaling. De prompt bevat merkcontext, tone of voice en juridische beperkingen van de doelmarkt.
Stap 3 — Opschoning: we verwijderen generieke, repetitieve zinnen ("dit product is perfect voor..."), corrigeren inconsistenties tussen talen (een product kan niet "150 ml" zijn in Spanje en "5 oz" in Frankrijk als we in heel Europa in ml verkopen) en passen stijlregels toe.
Stap 4 — Automatische validatie: elke gegenereerde tekst doorloopt controles op minimale/maximale lengte, aanwezigheid van productkeywords, afwezigheid van hallucinaties (verzonnen ingredienten, valse eigenschappen) en correct HTML-formaat voor Magento.
Cijfers van de pipeline
- Totale kosten: ~420 euro aan API-tokens voor de 81.000 teksten
- Verwerkingstijd: 14 uur voor de volledige generatie
- Automatisch goedgekeurd: 87% van de teksten slaagde zonder handmatige tussenkomst voor de validatie
- Handmatige controle: de overige 13% vereiste kleine aanpassingen (voornamelijk producten met bijzondere kenmerken die niet gedekt werden door de fabrikantgegevens)
Vergeleken met professionele vertaling (geschat op meer dan 120.000 euro en 4-6 maanden) betekende de AI-pipeline een besparing van 99,6% op kosten en 95% op tijd. De kwaliteit haalt niet het niveau van een senior copywriter, maar voor functionele, SEO-klare productbeschrijvingen is het ruimschoots voldoende.
Performancestack: Varnish, Redis, OPcache en PHP 8.4
Het resultaat spreekt voor zich: PageSpeed Insights 100 op mobiel voor een Magento 2 winkel met 15 store views en meer dan 60.000 producten. FCP van 1,4 seconden, LCP van 1,5 seconden, TBT van 30 ms en CLS van 0. Deze cijfers zijn uitzonderlijk voor elk ecommerceplatform, en al helemaal voor een op Magento gebouwd platform.

Performance is bij een ecommerce geen optie. Een trage site verliest omzet. Met 15 winkels die verkeer uit heel Europa bedienen, moet de stack solide zijn.
Cache-architectuur
De Magento-ontwikkeling die we voor Loviux opzetten, volgt een 4-laags hiërarchie:
- Varnish 7.x als reverse proxy: cachet volledige pagina's. Een Varnish-hit serveert een pagina in <10 ms zonder PHP aan te raken. We configureerden custom VCL voor selectieve purge per store view, categorie en product.
- Redis voor applicatiecache en sessies: elimineert schijftoegang. Twee aparte instanties: een voor configuratie-/blokcache (DB 0) en een voor sessies (DB 2).
- OPcache van PHP 8.4: precompileert de ~40.000 PHP-bestanden van Magento. Met
opcache.jit=tracingingeschakeld worden hot-path-functies gecompileerd naar native machinecode. - Full-page cache in Magento als fallback voor requests die Varnish omzeilen (ingelogde gebruikers, niet-lege winkelwagen).
Blokkerende CSS: een contra-intuïtieve keuze voor CLS 0
De gangbare wijsheid zegt: laad CSS asynchroon, extraheer critical CSS inline. Wij deden het tegenovergestelde. Alle CSS wordt blokkerend geladen in de <head>.
Waarom? Omdat met Hyva + Tailwind de totale CSS ~35 KB bedraagt (gzipped: ~8 KB). Blokkerend laden voegt enkele milliseconden toe aan de First Contentful Paint, maar garandeert dat de layout nooit verschuift na de eerste render. Het resultaat: een CLS (Cumulative Layout Shift) van 0,000 consistent op alle pagina's.
Bij een project met tientallen verschillende templates (home, categorie, product, checkout, CMS-pagina's x 15 winkels) zou het onderhouden van een critical-CSS-systeem een nachtmerrie zijn. Met 8 KB blokkerende CSS is de trade-off niet de moeite waard.
Zero-downtime deploy met symlink-switching
De productiedeploy volgt een flow die downtime voorkomt:
- Build in tijdelijke directory (
/var/www/releases/YYYYMMDD-HHMMSS/) composer install --no-dev,bin/magento setup:di:compile,bin/magento setup:static-content:deployvoor de 9 talen- Cache warm-up: we voeren requests uit naar belangrijke pagina's om Varnish te vullen
- Atomaire symlink-switch:
ln -sfnwijzigt de symlink/var/www/currentnaar de nieuwe release php-fpm reloadzodat de workers de nieuwe code laden- Selectieve Varnish-purge
Als er iets misgaat, is een rollback simpelweg de symlink terugwijzigen naar de vorige release. Downtime: 0 seconden.
De setup:static-content:deploy voor 9 talen duurt ~12 minuten. Het is de traagste stap in de pipeline, maar omdat deze voor de switch wordt uitgevoerd, heeft het geen impact op het live verkeer.
Technische SEO voor meerdere talen
Een ecommerce met 15 winkels en 9 talen is een mijnenveld voor technische SEO. Google moet begrijpen welke pagina bij welk land en welke taal hoort, zonder varianten te verwarren.
Hreflang op alle pagina's
Elke pagina bevat hreflang-tags die naar al haar varianten verwijzen:
Dat zijn 14 hreflangs per pagina. Met een catalogus van 60.000 producten gaat het om 168.000 hreflang-declaraties alleen al voor productpagina's. We genereren dit dynamisch met een module die de URL-rewrites van Magento per store view opvraagt. Bekijk de vibratorcatalogus om de schaal te begrijpen.
Volledige structured data
We implementeerden Schema.org JSON-LD op alle relevante pagina's:
- Product: met
offers,aggregateRating,brand,sku,gtin13indien beschikbaar. Google toont rich snippets met prijs en beschikbaarheid. - CollectionPage: op categoriepagina's, met
numberOfItemsen breadcrumb. - BreadcrumbList: volledige hierarchische navigatie (Home - Categorie - Subcategorie - Product).
- Organization: bedrijfsgegevens op de homepagina en contactpagina's.
- FAQPage: op categoriepagina's met veelgestelde vragen over producten.
Alles gevalideerd met de Rich Results Test van Google en zonder fouten in Search Console.
Gesplitste sitemaps per winkel
Een enkele sitemap voor 15 winkels zou de limiet van 50.000 URL's overschrijden. We genereren individuele sitemaps per store view:
loviux.nl/sitemap.xml- sitemap-index die verwijst naarsitemap-products.xml,sitemap-categories.xml,sitemap-cms.xml- Hetzelfde patroon voor elk domein (.es, .fr, .de, .it, .pt, .pl, .co.uk, .at, .ch, .be, .com)
Elke sitemap wordt dagelijks om 5:00 uur opnieuw gegenereerd en bevat <lastmod> op basis van de werkelijke laatste update van de content, niet de generatiedatum. Google waardeert eerlijke timestamps.
Belangrijke integraties
Brevo voor e-mailmarketing
We koppelden Magento aan Brevo (voorheen Sendinblue) voor automatisering van transactionele en marketing-e-mails:
- Bidirectionele contactsynchronisatie (registratie, aankoop, abandon)
- Transactionele e-mails (orderbevestiging, verzending, factuur) verstuurd via Brevo voor betere deliverability
- Workflows voor verlaten winkelwagen, gesegmenteerd per winkel en taal
GA4 Enhanced Ecommerce
We implementeerden de volledige GA4 Enhanced Ecommerce-tracking met 10 standaard events:
view_item, view_item_list, add_to_cart, remove_from_cart, view_cart, begin_checkout, add_shipping_info, add_payment_info, purchase en refund.
Elk event bevat de store-view-dimensie, zodat prestaties per land en taal kunnen worden gesegmenteerd in de rapporten.
Cloudflare Turnstile
We vervingen reCAPTCHA door Cloudflare Turnstile op alle formulieren: registratie, inloggen, contact, nieuwsbrief en checkout als gast. Turnstile toont geen zichtbare challenges aan de gebruiker (standaard onzichtbaar) en heeft een hoger slagingspercentage dan reCAPTCHA v3. Bij een webshop is elke extra frictie in de checkout een gemiste verkoop.
Wat we meenemen uit dit project
Na maanden van ontwikkeling, testen en optimalisatie zijn dit de inzichten die de meeste impact hadden:
- Hyva is niet optioneel voor nieuwe Magento 2-projecten. Als je vandaag een project start met Luma, begin je met technische schuld. Het prestatieverschil is simpelweg te groot.
- Het taal-fallbacksysteem ontwerp je voordat je het eerste product inlaadt. Dit achteraf doen met 60.000 producten die al geladen zijn, zou een nachtmerrie van datamigraties zijn geweest.
- Magewire is het juiste antwoord voor checkout in Hyva. Hetzelfde paradigma als de rest van de frontend, zonder extra afhankelijkheden. Laravel Livewire bewees het concept; Magewire brengt het naar Magento.
- AI voor productcontent vervangt geen copywriters, maar schaalt waar zij niet kunnen. 81.000 teksten in 9 talen voor 420 euro is een vergelijking die geen discussie toelaat. Menselijke controle blijft nodig voor de 10-15% randgevallen.
- Blokkerende CSS met Hyva is logischer dan critical CSS. Wanneer je totale CSS minder weegt dan een profielfoto, loont de complexiteit van critical-CSS-onderhoud simpelweg niet.
- Zero-downtime deploy is verplicht, geen extraatje. Met 15 winkels en 24/7 verkeer uit meerdere tijdzones bestaat er geen veilig onderhoudsvenster.
Als je bedrijf een Magento 2-ecommerce moet opschalen, of het nu gaat om een migratie naar Hyva, een multi-store-configuratie of complexe integraties, neem contact op met ons team. We bouwen al meer dan 15 jaar ecommerce-oplossingen die werken op echte schaal.