Migration
Van Joomla 3 naar Astro: de rekensom die het besliste
Een Nederlandse tandartsketen vroeg ons om hun Joomla 3-site nog dit jaar naar Joomla 5 te tillen. We openden een spreadsheet, deden de rekensom en bouwden hem in plaats daarvan opnieuw in Astro.

Eind januari 2026. Een tandartsketen met vier locaties in Utrecht stuurde een mailtje naar hun accountmanager. Hun Joomla 3.10-site stond al ruim een jaar gele waarschuwingen te knipperen in de admin. De booking-iframe hing op een deprecated PHP-functie. Hun shared host had ze negentig dagen gegeven om van PHP 7.4 af te zijn. De vraag: migreren naar Joomla 5, vóór april.
We zeiden ja tegen het gesprek, nog niet tegen de migratie. Twee uur in de audit lag er een ander voorstel op tafel: Joomla 5 helemaal overslaan en de site opnieuw bouwen als een statisch Astro-project. De tandartsgroep keurde het in de tweede meeting goed. Dit is de rekensom die we lieten zien.
Wat Joomla 5 eigenlijk vraagt
Er bestaat een prettige aanname dat de stap van Joomla 3 naar Joomla 5 een lange druk op de knop is. Dat klopt niet.
Joomla 3 bereikte op 17 augustus 2023 het einde van zijn levensduur. Security-fixes stopten die dag. Om bij Joomla 5 uit te komen ga je eerst langs Joomla 4, en je Joomla 3-template kun je niet meenemen. Templates die op het J3-systeem waren gebouwd, moesten in J4 plaatsmaken voor een nieuw layout-, child template- en media manager-systeem. De meeste third-party templates uit de periode 2014 tot 2019 hebben nooit een 4-compatibele release uitgebracht. De onze was er één van.
Hetzelfde probleem geldt voor extensies. De site van de kliniek gebruikte K2 voor service-artikelen, een custom wrapper rond de booking-iframe, een SEF-override en een oude gallery-plugin. K2 kreeg pas eind 2022 een stabiele Joomla 4-build. De SEF-override werd in 2017 verlaten. De gallery-plugin had een ongepatchte XSS die we op webserverniveau moesten dichttimmeren.
Een 'migratie' betekende in dit geval dus:
- J3.10 upgraden naar de laatste patch level, daarna naar J4, daarna naar J5.
- De template herbouwen op het J4-layoutsysteem.
- Drie extensies vervangen en alle code refactoren die ervan afhing.
- Custom PHP refactoren die
JFactory,JRouteenJTextaanraakte (hernoemd in J4). - De host naar PHP 8.1 of 8.2 brengen en onderweg elke deprecation oplossen.
- Dezelfde oefening overdoen in oktober 2025 wanneer Joomla 4 zelf end of life gaat.
Onze conservatieve schatting kwam uit op 95 tot 110 uur, plus een hertest van elke pagina, plus de volgende geforceerde upgrade-cyclus die al in zicht stond.
De statische optie op papier
De site had 124 pagina's: 4 locatiepagina's, 1 hoofdservicepagina met 14 detailpagina's, 9 teamprofielen, een FAQ, een contactpagina, een EN-spiegel van al het bovenstaande en grofweg 70 blogposts vanaf 2017.
Content-updates gebeurden hooguit twee keer per maand: een nieuw teamlid, een melding over openingstijden, een whitening-actie. De eigenaar schreef af en toe een blogpost. De praktijkmanager schreef het merendeel.
Niets op de site was gepersonaliseerd. De boekingsflow zat in een third-party widget. Reviews kwamen uit een Google Places-embed. Het contactformulier postte naar een CRM-endpoint. De site was qua gedrag al statisch. De Joomla-installatie draaide een database om content te renderen die tussen deploys nooit veranderde.
We modelleerden de herbouw als een Astro 5-project met content collections, het bestaande design overgezet naar een verse componentenbibliotheek, en een klein editor-oppervlak op basis van TinaCMS voor de praktijkmanager. Totale schatting: 65 tot 75 uur.
De cijfers die de doorslag gaven
We legden beide paden naast elkaar voor de CFO van de tandartsgroep. Ronde getallen, geen beloftes.
- Joomla 5-migratie: 95 tot 110 dev-uren, plus een J4 end-of-life-cyclus in oktober 2025, plus €52 per maand aan managed VPS-hosting, plus een maandelijks patch-venster.
- Astro-herbouw: 65 tot 75 dev-uren, geen CMS-runtime om te patchen, €0 tot €20 per maand aan statische hosting, en geen geforceerde upgrade-cyclus tot ze er zelf voor kiezen.
De migratie had een site opgeleverd die er hetzelfde uitzag en draaide op dezelfde architectuur waar ze al jaren stilletjes hun geduld op verloren. De herbouw kostte minder uren, haalde een categorie terugkerende uitgaven weg en leverde een snellere site op. De CFO zette dezelfde week zijn handtekening.
Bouwweek
Content uit Joomla trekken
We namen een database dump en bevraagden de content-tabellen direct om alles naar markdown te exporteren.
SELECT id, title, alias, introtext, `fulltext`, language, publish_up
FROM jos_content
WHERE state = 1
ORDER BY publish_up DESC;
K2-artikelen woonden in jos_k2_items, gejoined met jos_k2_categories voor de service-groepering. Een kort Node-script liep door de rijen, schoonde de HTML op (TinyMCE laat een decennium aan lege <p>-tags en zwervende 's achter), downloadde afbeeldingen uit /images/stories/ en schreef per pagina één markdown-bestand naar een content collection.
Astro content collections
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const services = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
slug: z.string(),
locale: z.enum(['nl', 'en']),
summary: z.string().max(180),
publishedAt: z.coerce.date(),
cover: z.string().optional(),
}),
});
export const collections = { services };
Dezelfde shape werkte voor teamprofielen en blogposts met andere schema's. Vertaalkoppels werden gekoppeld via de slug, zodat de taalwisselaar de EN-versie van elke NL-pagina kon vinden zonder routing-tabel.
Redirects en URL-stabiliteit
De oude Joomla-SEF-URL's gebruikten een mix van /component/k2/item/123-some-slug voor servicepagina's en een lange staart aan /index.php?option=com_content&view=article&id=45-fallbacks die door de jaren heen in backlinks waren gelekt. We mapten beide naar schone nieuwe paden via vercel.json en een statisch redirect-manifest, gegenereerd vanuit hetzelfde Node-script dat de content exporteerde. Twee weken na livegang rapporteerde Search Console minder dan één procent 404's op geïndexeerde URL's, en zat het organisch verkeer op servicepagina's binnen vier procent van de baseline van vóór de launch.
Booking-iframe en contactformulier
De boekingswidget hield zijn iframe. Het contactformulier werd een Vercel serverless function die naar dezelfde CRM-endpoint postte, met een Cloudflare Turnstile-check erbovenop. Het Google Places-reviewblok werd een kleine client-component die alleen op de locatiepagina hydrate.
Cijfers na livegang
De nieuwe site ging live op 28 maart 2026. We namen de week ervoor een baseline van de oude site en maten de nieuwe op hetzelfde verbindingsprofiel.
- Largest Contentful Paint op een mid-range Android over throttled 4G: 3,8s op Joomla, 0,9s op Astro.
- Build-to-live voor een content-edit: 41 seconden via Vercel.
- Hosting: van €52 per maand managed VPS met back-ups naar €0 op de Vercel free tier (de site past ruim binnen de bandwidth-allocatie).
- Publiek aanvalsoppervlak: van één PHP-runtime plus vier extensies naar een statische CDN plus één form-endpoint.
Wat de eigenaar van de kliniek het meest verraste, was de editing-ervaring. De praktijkmanager mijdde de Joomla-backend al jaren. De nieuwe editor opent een side-by-side preview, laat haar in-place bewerken en commit naar git bij opslaan. Ze publiceerde 11 blogposts in de acht weken na livegang. Het hele voorgaande jaar publiceerde ze er 4.
Als een site zich al gedraagt als een statische site, betaal je voor runtime die je niet gebruikt zodra je een CMS-migratie afrekent.
Gevallen waarin Joomla 5 wél wint
We willen het niet groter maken dan het is. Joomla 5 is het juiste antwoord als:
- De site echt CMS-gedrag heeft: content per gebruiker, ACL-bomen, ledenomgevingen, formulieren met workflow.
- Een team van niet-technische bijdragers al thuis is in Joomla en de kosten om ze een nieuwe editor aan te leren zwaarder wegen dan de migratie.
- Een native extensie écht werk doet. Een serieuze webshop op VirtueMart, een echte community op EasySocial, een gedegen membership-stack.
- De custom code klein is, de template al J4-klaar is en alle third-party extensies een actuele J5-release hebben.
Voor de tandartsgroep uit Utrecht gold geen van die punten. Voor de meeste verouderde Joomla-sites die we doorlichten, gelden ze ook niet. Het CMS sleepte al jaren statische content mee, en de migratiefactuur was de prijs om dat zo te houden.
Een audit van vijf minuten voordat je de migratie boekt
Voordat je een Joomla 5-offerte tekent, open de site en beantwoord drie vragen eerlijk.
- Hoeveel pagina's zijn er in de afgelopen 12 maanden daadwerkelijk veranderd?
- Hoeveel user accounts loggen in en doen iets anders dan content bewerken?
- Hoeveel van je geïnstalleerde extensies doen werk dat een statische site, een serverless function en één third-party widget niet net zo goed zouden afhandelen?
Als de antwoorden 'minder dan dertig', 'nul' en 'één of twee' zijn, betaal je voor het onderhouden van een runtime die je niet gebruikt.
Toen we de nieuwe site bouwden voor de tandartsgroep in Utrecht, was het lastigste niet de Astro-build. Het was negen jaar klinische content doorlezen en bepalen wat we behielden. We draaien diezelfde audit voor elke offerte voor een legacy-migratie, en meestal kleurt die het voorstel meer dan de gekozen stack.
Kern
Voordat je betaalt voor een Joomla 5-migratie: tel wat er het afgelopen jaar daadwerkelijk veranderd is op de site. Onder de dertig pagina's en je betaalt voor runtime die je niet gebruikt.
FAQ
Werkt Astro als ons team vaak content bewerkt?
Ja. Met een git-backed editor zoals TinaCMS of Decap bewerkt een niet-technische bijdrager in een live preview en slaat op naar de repo. Builds redeployen binnen een minuut op Vercel of Netlify.
Wat gebeurt er met onze bestaande Joomla-rankings in Google?
Die behoud je met een redirect-manifest van oude SEF-URL's naar schone nieuwe paden, gegenereerd vanuit hetzelfde export-script. Houd Search Console de eerste twee weken in de gaten en repareer eventuele staart-404's.
Kunnen we onze third-party booking-widget houden?
Ja. Iframe-widgets nemen we ongewijzigd mee. Alles wat met een CRM of webhook praatte, wordt een kleine serverless function op de nieuwe host. Meestal een port van één dag.
Is Joomla 5 altijd de verkeerde keuze voor een Joomla 3-site?
Nee. Als de site echte ledenomgevingen heeft, ACL-bomen, native shop- of community-extensies, of een team dat al vloeiend is in Joomla, is een Joomla 5-migratie nog steeds het goedkopere pad.