Ik heb in de afgelopen drie jaar ongeveer 40 projecten naar Sanity gemigreerd. Sommige waren schone tweewekelijkse sprints. Anderen werden driemandenmaratons die me deden twijfelen aan mijn carrièrekeuzes. Het verschil hangt bijna nooit af van het bron-CMS — het komt neer op voorbereiding, content modeling-besluiten en eerlijk zijn over waarmee je jezelf eigenlijk inlaat.

Dit is de handleiding die ik had willen hebben toen ik CMS-migraties begon. Het behandelt overstappen van WordPress, Contentful en Drupal naar Sanity's GROQ-gestuurde wereld. Ik zal eerlijk zijn over waar Sanity goed is, waar het je frustreert, en hoe de realistische tijdlijnen eruit zien.

Inhoudsopgave

Sanity Migratiehandleiding: Overstappen van WordPress, Contentful of Drupal

Waarom teams in 2025 naar Sanity overstappen

Laten we eerst de voor de hand liggende dingen uit de weg ruimen. Sanity's realtime collaboratief bewerken, aanpasbare Studio, en gestructureerde content-benadering zijn echt goed. Maar de reden waarom de meeste teams met ons contact opnemen over migratie, is niet omdat ze een blogpost hebben gelezen over Sanity's functies. Het is omdat iets kapot ging.

WordPress-sites raken schaallimieten rond 50.000+ stuks content met complexe aangepaste post types. Contentful's prijsmodel begint te knellen op enterprise-niveau — we hebben teams gezien die te maken krijgen met $3.500+/maand facturen voor wat eigenlijk een content API is. Drupal-teams kunnen developers niet meer vinden, althans niet degenen die in 2025 met PHP-templating willen werken.

Sanity's prijsmodel is voor de meeste teams echt voorspelbaarder. De gratis tier dekt tot 100.000 API-verzoeken/maand en 500K assets. Het Growth-plan op $99/maand/project biedt je 2,5 miljoen API-verzoeken en 1 miljoen assets. Ter vergelijking: Contentful's Team-plan kost $300/maand en Contentful's Premium-tier kan gemakkelijk $2.000+/maand overschrijden.

Maar hier is mijn eerlijke mening: als je huidige CMS goed werkt en je team productief is, migreer dan niet gewoon omdat Sanity nieuwer of cooler is. Migraties kosten altijd meer dan je denkt.

Pre-migratie-audit: De stap die iedereen overslaat

Voordat je een enkele regel migratiecode schrijft, heb je een content-audit nodig. Niet een snelle scan — een echte audit. Dit ziet er zo uit:

Content-inventaris

Documenteer elk contenttype, elk veld, elke relatie. Ik gebruik een spreadsheet met deze kolommen:

  • Naam contenttype
  • Totaal aantal items
  • Velden (met types)
  • Relaties met andere contenttypes
  • Media-bijlagen (aantal en totale grootte)
  • Aangepaste functionaliteit (shortcodes, widgets, embeds)
  • Datum laatste wijziging
  • Nog steeds relevant? (Ja/Nee/Misschien)

Je zult verbaasd zijn hoeveel content dood gewicht is. Bij een WordPress-migratie had een klant 12.000 posts. Na de audit waren slechts 4.200 nog relevant. Dat is 65% minder content om te migreren, testen en valideren.

Technische afhankelijkheidsmapping

Zet elke plugin, module of integratie op een lijst die je huidige CMS gebruikt. Voor elk bepaal je:

  1. Kan Sanity dit native afhandelen?
  2. Is er een Sanity-plugin voor?
  3. Moeten we een aangepaste oplossing bouwen?
  4. Kunnen we dit helemaal laten vallen?

Deze mapping alleen zal je al weken verassingen besparen.

Beoordeeling teamgereedheid

Sanity Studio is op React gebaseerd. Je content-editors hebben training nodig. Je developers moeten GROQ leren (of GraphQL gebruiken, hoewel GROQ waar Sanity echt goed in is). Budget 1-2 weken voor team-onboarding — niet als iets leuks, maar als regelitem.

WordPress naar Sanity-migratie

WordPress is het meest voorkomende bron-CMS waarvandaan we migreren. Het is ook het lastigst, omdat WordPress niet alleen een CMS is — het is een volledig toepassingsplatform waarop mensen alles hebben vastgeschroefd.

Wat schoon overkomt

  • Posts en pagina's (basisinhoud)
  • Categorieën en tags
  • Uitgelichte afbeeldingen
  • Auteurgegevens
  • Basisvelden op maat (ACF, Meta Box)

Wat wordt ingewikkeld

  • Gutenberg-blokken: Elk bloktype moet overeenkomen met een Sanity Portable Text aangepast blok of objecttype. Als je 15+ aangepaste Gutenberg-blokken hebt, budget aanzienlijke tijd hier.
  • Shortcodes: Deze moeten worden geparsd, geïnterpreteerd en omgezet naar Portable Text-annotaties of aangepaste blokken. WPBakery- en Elementor-shortcodes zijn bijzonder vervelend.
  • Door plugins gegenereerde content: WooCommerce-producten, Yoast SEO-gegevens, ACF-herhalingsvelden — elk vereist aangepaste migratielogica.
  • Mediabibliotheek: WordPress slaat meerdere afbeeldingsgroottes op. Sanity voert afbeeldingstransformaties on-the-fly uit, dus je hebt alleen de originals nodig. Maar de originals vinden in een rommelige wp-uploads-map? Leuk.

Migratiescript-benadering

Ik gebruik meestal een Node.js-script dat de WordPress REST API aanroept en schrijft naar Sanity's mutation API:

import { createClient } from '@sanity/client'
import fetch from 'node-fetch'

const sanity = createClient({
  projectId: 'your-project-id',
  dataset: 'production',
  token: process.env.SANITY_WRITE_TOKEN,
  apiVersion: '2025-01-01',
  useCdn: false,
})

const WP_API = 'https://yoursite.com/wp-json/wp/v2'

async function migratePosts(page = 1) {
  const res = await fetch(`${WP_API}/posts?per_page=100&page=${page}`)
  const posts = await res.json()
  const totalPages = res.headers.get('x-wp-totalpages')

  const transaction = sanity.transaction()

  for (const post of posts) {
    transaction.createOrReplace({
      _id: `wp-post-${post.id}`,
      _type: 'post',
      title: post.title.rendered,
      slug: { current: post.slug },
      publishedAt: post.date,
      // Body vereist HTML-naar-Portable Text-conversie
      body: await convertToPortableText(post.content.rendered),
    })
  }

  await transaction.commit()
  console.log(`Gemigreerde pagina ${page} van ${totalPages}`)

  if (page < totalPages) {
    await migratePosts(page + 1)
  }
}

De convertToPortableText-functie is waar 80% van de complexiteit zit. Ik gebruik het @sanity/block-tools-pakket gecombineerd met jsdom voor HTML-parsing. Het handelt basis-HTML goed af, maar aangepaste elementen en shortcodes hebben afzonderlijke handlers nodig.

Realistische tijdlijn

Voor een typische WordPress-site met 500-2.000 posts, standaard aangepaste velden en een handvol aangepaste post types: 4-8 weken inclusief content modeling, migratiescript, validatie en editor training.

Sanity Migratiehandleiding: Overstappen van WordPress, Contentful of Drupal - architectuur

Contentful naar Sanity-migratie

Contentful-naar-Sanity is eigenlijk het soepelste migratieppad van de drie. Waarom? Omdat beide gestructureerde content-platforms zijn met soortgelijke mentaliteiten. Je content is al in een headless CMS met gedefinieerde contenttypes en velden.

Belangrijkste verschillen om rekening mee te houden

Functie Contentful Sanity
Rijke tekst Rich Text (JSON-gebaseerd) Portable Text (JSON-gebaseerd)
Content modeling Web UI Code-gedefinieerde schemas
Querytaal GraphQL / REST GROQ (+ GraphQL)
Lokalisatie Ingebouwd veld-niveau Plugin of aangepast
Referenties Links (Entry/Asset) Referenties met types
Webhooks Ja Ja
Asset-afhandeling Ingebouwde CDN Sanity CDN + hotspot/crop
Prijzen (midden-tier) ~$300/mnd (Team) $99/mnd (Growth)

Conversie rijke tekst

Contentful's Rich Text en Sanity's Portable Text zijn beide JSON-gebaseerd, wat geweldig is. Maar ze hebben verschillende structuren. Je zult een transformer moeten schrijven:

function contentfulRichTextToPortableText(richTextField) {
  return richTextField.content.map(node => {
    switch (node.nodeType) {
      case 'paragraph':
        return {
          _type: 'block',
          style: 'normal',
          children: node.content.map(mapInlineContent),
        }
      case 'heading-2':
        return {
          _type: 'block',
          style: 'h2',
          children: node.content.map(mapInlineContent),
        }
      case 'embedded-entry-block':
        // Wijs toe aan je aangepaste Portable Text-type
        return mapEmbeddedEntry(node)
      // ... behandel alle node types
    }
  }).filter(Boolean)
}

Contenttype naar schema-mapping

Contentful-contenttypes worden redelijk direct toegewezen aan Sanity-document- en objecttypes. De grootste verschuiving is dat Sanity-schemas in code worden gedefinieerd (JavaScript/TypeScript), niet in een web UI. Dit is eigenlijk een groot voordeel — je content model bestaat in versiebeheer.

Gebruik de Contentful Management API om je content model te exporteren, schrijf dan een script dat Sanity-schemabestanden genereert:

contentful space export --space-id YOUR_SPACE_ID --export-dir ./export

Realistische tijdlijn

Voor een Contentful-ruimte met 10-20 contenttypes en 5.000-10.000 entries: 3-5 weken. Het is sneller omdat je al in gestructureerde content denkt.

Drupal naar Sanity-migratie

Drupal-migraties zijn degenen die me een tweede koffie doen inschenken. Niet omdat Drupal slecht is — het is een krachtig systeem. Maar Drupal-sites zijn meestal oud, tot in het extreme aangepast, en draaien op infrastructuur die niemand volledig snapt.

De Drupal-specifieke uitdagingen

  • Contenttypes met 50+ velden: Drupal maakt het gemakkelijk om velden toe te voegen. Te gemakkelijk. Ik heb contenttypes gezien met 80 velden, waarvan de helft ongebruikt is.
  • Taxonomietermijnreferenties: Drupal's taxonomiesysteem is flexibel maar kan diep geneste hiërarchieën creëren die voor Sanity moeten worden afgevlakt.
  • Paragraphs-module: Als de site Drupal Paragraphs gebruikt (en de meeste moderne Drupal-sites doen dat), wordt elk type paragraaf een Portable Text-bloktype of Sanity-object. Dit is de grootste enkele taak.
  • Media-entiteiten: Drupal 9/10's mediasysteem is complexer dan dat van WordPress. Meerdere mediatypen, herbruikbare media-entiteiten en veldconfiguraties voor bestanden moeten allemaal worden toegewezen.
  • Meertalige content: Drupal's vertaalsysteem is geavanceerd. Sanity heeft niet ingebouwde lokalisatie op hetzelfde niveau — je zult de @sanity/document-internationalization-plugin of een veld-niveau-benadering nodig hebben.

Migratiebenadering

Ik gebruik de voorkeur aan Drupal's JSON:API-module (opgenomen in Drupal-kern sinds 9.x) als extractielaag:

async function fetchDrupalContent(type, page = 0) {
  const limit = 50
  const offset = page * limit
  const url = `${DRUPAL_URL}/jsonapi/node/${type}?page[limit]=${limit}&page[offset]=${offset}&include=field_image,field_paragraphs`

  const res = await fetch(url, {
    headers: { Authorization: `Basic ${DRUPAL_AUTH}` },
  })
  return res.json()
}

Voor oudere Drupal 7-sites zonder JSON:API, moet je misschien rechtstreeks in de database opvragen. Drupal 7's databaseschema is... een ervaring. De field_data_*-tabellen zullen je dromen achtervolgen.

Realistische tijdlijn

Drupal-migraties variëren enorm. Een eenvoudige Drupal 10-site met 5-10 contenttypes: 5-8 weken. Een legacy Drupal 7-site met 30+ contenttypes, Paragraphs en meertalige content: 8-16 weken. Ik overdrijf niet.

Content Modeling: Je schema's goed krijgen

Hier is het wat de meeste migratiehandleidingen je niet zullen vertellen: repliceer je oude content model niet in Sanity. Dit is je kans om jaren waarderingsverlies aan content recht te zetten.

Veelvoorkomende modelleringsfouten

  1. Een 1:1-veldmapping maken: Alleen omdat WordPress een aangepast veld "ondertitel" had, betekent niet dat Sanity er een nodig heeft. Misschien zou het onderdeel van een gestructureerd "hero"-object moeten zijn.
  2. Objects te diep nesten: Sanity laat je objects diep nesten. Weersta de verleiding. Vlakke(-ish) schema's zijn gemakkelijker om mee te queryen met GROQ en gemakkelijker voor editors om mee te werken.
  3. De kracht van Portable Text negeren: Zet HTML niet zomaar in een enkel tekstveld. Ontwerp aangepaste bloktypen die overeenkomen met je content-patronen. Een "callout"-blok, een "code snippet"-blok, een "afbeelding met bijschrift"-blok — deze maken het leven van editors beter.

Schemaontwerp-proces

Ik volg deze volgorde:

  1. Audit bestaande content (gedaan in pre-migratie)
  2. Identificeer de daadwerkelijke content-patronen (niet wat de CMS afdwong)
  3. Ontwerp schemas eerst op papier/whiteboard
  4. Bouw schemas in code
  5. Importeer een kleine testbatch (50-100 items)
  6. Laat editors de Studio-ervaring testen
  7. Herhaal schemas voordat je volledige migratie

Stappen 5-7 zijn kritiek en worden vaak overgeslagen. We hebben meer geschreven over content modeling-benaderingen in ons headless CMS-ontwikkelingwerk.

Datamigratie-strategieën en hulpmiddelen

Essentiële hulpmiddelen

  • @sanity/client: De officiële JavaScript-client voor het lezen/schrijven van Sanity-gegevens
  • @sanity/block-tools: Converteert HTML naar Portable Text
  • sanity dataset import/export: CLI-tools voor volledige datasetoperaties
  • ndjson: Sanity gebruikt newline-delimited JSON voor imports — word ermee vertrouwd
  • jsdom of htmlparser2: Voor HTML-parsing tijdens rich text-conversie

Migratiearchitectuur

Ik structureer elke migratie als een pijplijn met vier stadia:

Extract → Transform → Load → Validate

Elk stadium is een apart script. Dit is belangrijk omdat je de migratie meerdere keren zult uitvoeren — meestal 5-10 keer voordat de definitieve productierun. Met afzonderlijke stadia kun je alleen de onderdelen opnieuw uitvoeren die moeten worden gerepareerd.

# Extract
node scripts/extract-wordpress.js > data/raw-posts.ndjson

# Transform
node scripts/transform-posts.js < data/raw-posts.ndjson > data/sanity-posts.ndjson

# Load
sanity dataset import data/sanity-posts.ndjson production --replace

# Validate
node scripts/validate-migration.js

Assets afhandelen

Afbeeldingen en bestanden zijn altijd het traagste gedeelte. Sanity's asset-pijplijn is goed, maar het uploaden van 10.000 afbeeldingen duurt tijd. Tips:

  • Upload assets eerst, onderhoud een mapping van oude URL's naar nieuwe Sanity-asset-ID's
  • Gebruik gelijktijdige uploads (maar respecteer rate limits — 25 req/sec voor het Growth-plan)
  • Controleer afbeeldingsafmetingen en formaten vóór upload
  • Migreer geen miniatuursizes — Sanity genereert deze on-the-fly via zijn afbeeldings-CDN

De verborgen kosten waar niemand over praat

Laat me eerlijk zijn over kosten die niet in de typische migratieramming voorkomen.

URL-omleidingen

Als je je frontend wijzigt (wat je waarschijnlijk doet als je naar een headless CMS gaat), heb je URL-mapping nodig. Elke. Enkele. URL. Voor SEO is dit niet onderhandelbaar. Een site met 5.000 pagina's heeft 5.000 omleidingsregels nodig. Hulpmiddelen zoals next.config.js-omleidingen of Vercel's _redirects-bestand kunnen dit afhandelen, maar iemand moet de mapping bouwen.

SEO-metadata-migratie

Yoast SEO-gegevens uit WordPress. Metatag-module-gegevens uit Drupal. Contentful's SEO-velden. Dit allemaal moet overkomen. Aangepaste meta-titels, beschrijvingen, Open Graph-afbeeldingen, canonieke URL's, gestructureerde gegevens — het is een project binnen het project.

Editor-training en documentatie

Budget minstens 2-4 dagen. Sanity Studio is intuïtief, maar het verschilt van wat je editors kennen. We maken meestal aangepaste Studio-documentatie met schermafbeeldingen en nemen 3-5 walkthrough-video's op.

Frontend-ontwikkeling

Dit is de olifant in de kamer. Het migreren van content naar Sanity is slechts de helft van het project. Je hebt ook een frontend nodig die de content consumeert. Of je Next.js, Astro of een ander framework gebruikt, de frontend-build is vaak 50-70% van de totale projectkosten. Bekijk ons werk met Next.js en Astro als je frontend-opties evalueert.

Tijdlijn en budgetvergleking

Gebaseerd op projecten die we in 2024-2025 hebben voltooid:

Migratieppad Content-volume Complexiteit Tijdlijn Budgetbereik
WordPress → Sanity < 1.000 pagina's Laag 3-5 weken €7.500-€14.000
WordPress → Sanity 1.000-10.000 pagina's Gemiddeld 6-10 weken €14.000-€33.000
WordPress → Sanity 10.000+ pagina's Hoog 10-16 weken €33.000-€70.000
Contentful → Sanity < 5.000 entries Laag-Gemiddeld 3-5 weken €6.500-€17.000
Contentful → Sanity 5.000-20.000 entries Gemiddeld 5-8 weken €17.000-€37.500
Drupal → Sanity < 2.000 nodes Gemiddeld 5-8 weken €11.000-€23.500
Drupal → Sanity 2.000-15.000 nodes Hoog 8-14 weken €23.500-€56.000
Drupal 7 → Sanity Willekeurig Zeer hoog 10-20 weken €33.000-€84.000

Opmerking: Deze bereiken betreffen alleen content-migratie. Frontend-ontwikkeling komt daar bovenop. Neem contact met ons op via /pricing voor projectspecifieke ramingen.

Deze nummers omvatten content modeling, migratiescript, datavalidatie en basistraining voor editors. Ze bevatten geen frontend-ontwikkeling, design of doorlopend onderhoud.

Post-migratiechecklist

Hier is de checklist die ik bij elke migratie gebruik:

  • Alle contenttypes gemigreerd en geverifieerd
  • Alle referenties/relaties intact
  • Alle afbeeldingen en bestanden geüpload en correct gekoppeld
  • Rich text content wordt correct weergegeven (controleer op kapotte opmaak)
  • URL-omleidingen aanwezig en getest
  • SEO-metadata gemigreerd (titels, beschrijvingen, OG-gegevens)
  • XML-sitemap opnieuw gegenereerd
  • Search console bijgewerkt met nieuwe sitemap
  • Analytics-tracking behouden
  • Editor-accounts aangemaakt en machtigingen ingesteld
  • Editor-training voltooid
  • Content-preview (draft mode) werkend
  • Webhooks geconfigureerd voor build-triggers
  • Backup van bron-CMS-gegevens gearchiveerd
  • DNS-wijzigingen gepland (indien van toepassing)
  • Prestatiebaseline gemeten
  • 404-monitoring ingesteld voor eerste 30 dagen

Dat laatste punt is belangrijk. Ongeacht hoe grondig je URL-omleiding is, zullen enkele URL's ontsnappen. Controleer je 404's agressief in de eerste maand.

Veelgestelde vragen

Hoe lang duurt een typische WordPress naar Sanity-migratie? Voor een standaard WordPress-site met minder dan 2.000 posts en eenvoudige aangepaste velden, verwacht 4-8 weken. Dit omvat content modeling, migratiescript, datavalidatie en editor training. Sites met complexe Gutenberg-blokken, WooCommerce, of meertalige content kunnen 10-16 weken duren. Het content-volume maakt minder uit dan de complexiteit van je contenttypes.

Kan ik van Contentful naar Sanity migreren zonder gegevens te verliezen? Ja, en het is eigenlijk het schoonste migratiepad van de drie die ik hier behandel. Beide platforms gebruiken gestructureerde, JSON-gebaseerde content, dus de mapping is relatief eenvoudig. Rich text moet worden geconverteerd van Contentful's formaat naar Portable Text, en referenties moeten opnieuw worden toegewezen, maar je zou geen gegevens moeten verliezen. Ik raad aan om de migratie eerst op een staging-dataset uit te voeren en een grondige content-vergelijking te doen voordat je overschakelt.

Wat gebeurt er met mijn SEO-rankings tijdens een CMS-migratie? Dit is de vraag die marketing-directeurs 's nachts wakker houdt. Als je omleidingen correct afhandelt, je URL-structuur waar mogelijk behoudt, en alle SEO-metadata migreert, zou je minimale impact moeten zien. Google's eigen documentatie zegt dat correct omgeleide migraties een tijdelijk dip van 2-4 weken kunnen zien voordat ze herstellen. Het sleutelwoord is "correct". Sla de URL-omleidingsmapping over en je zult je rankings kapotmaken. We hebben het zien gebeuren.

Is Sanity goedkoper dan Contentful voor enterprise-gebruik? In de meeste gevallen, ja — soms aanzienlijk. Sanity's Growth-plan op $99/maand dekt wat je voor Contentful's $300/maand Team-plan nodig hebt. Op enterprise-schaal wordt het verschil groter. Contentful's Premium-prijzen worden niet openbaar gepubliceerd, maar typisch $2.000-$4.000+/maand. Sanity Enterprise-prijzen zijn ook aangepast maar in het algemeen lager voor gelijk gebruik. Het echte kostenverschil zit in API-oproepen — Sanity's inbegrepen limieten zijn royaler.

Zou ik mijn Drupal 7-site naar Sanity moeten migreren of eerst upgraden naar Drupal 10? Ga rechtstreeks naar Sanity. Migreren van Drupal 7 naar Drupal 10 is bijna zoveel werk als naar een ander CMS migreren — de architectuur is ertussen zo drastisch veranderd. Als je al investeert in een grote migratie, kun je net zo goed naar het platform gaan dat je op lange termijn echt wilt gebruiken. De één uitzondering: als je team diep in het Drupal-ecosysteem zit en alleen wil moderniseren, is Drupal 10 met een headless frontend een geldig pad.

Moet ik mijn frontend opnieuw bouwen bij migratie naar Sanity? Als je van een monolithisch CMS zoals WordPress of Drupal komt, ja — je hebt een nieuwe frontend nodig omdat Sanity headless is. Dit is meestal het grotere gedeelte van het project. Als je van Contentful komt, kun je je bestaande frontend vaak hergebruiken met gewijzigde API-oproepen, vooral als je al Next.js of soortgelijk framework gebruikt. We behandelen zowel de CMS-migratie als frontend-builds als geïntegreerde projecten.

Kan ik mijn oude CMS en Sanity parallel runnen tijdens migratie? Absoluut, en ik raad het aan. Zet beide systemen 2-4 weken na je initiële migratie parallel. Editors kunnen in het oude CMS blijven werken terwijl je gegevens in Sanity valideert. Zet gewoon de content in het oude systeem op pauze voordat je definitieve migratierun — je wilt geen bewegend doelwit achtervolgen. Sommige teams stellen een "content freeze"-datum 48 uur voor de definitieve overstap in.

Wat is de grootste fout die teams maken tijdens een Sanity-migratie? Proberen hun oude CMS-structuur exact in Sanity te repliceren. Ik zie dit constant. Teams komen van WordPress en proberen WordPress-vormige schema's in Sanity te bouwen — generieke "page"-types met flexibele layouts in plaats van doelopgestelde contenttypes. Sanity's sterkte is gestructureerde content. Gebruik de migratie als een gelegenheid om je content correct te modelleren. Besteed een extra week aan content modeling. Het zal je maanden pijn besparen. Als je begeleiding hierover wilt, neem contact met ons op — content modeling is een van de dingen waaraan we de meeste tijd in migratieprojecten besteden.