Sanity Migration Playbook: Moving from WordPress, Contentful, or Drupal

He migrado alrededor de 40 proyectos a Sanity en los últimos tres años. Algunos fueron sprints limpios de dos semanas. Otros se convirtieron en maratones de tres meses que me hicieron cuestionarme mis decisiones profesionales. La diferencia casi nunca depende del CMS de origen — depende de la preparación, las decisiones de modelado de contenido, y ser honesto acerca de lo que realmente estás asumiendo.

Esta es la guía que desearía haber tenido cuando comencé a hacer migraciones de CMS. Cubre el movimiento desde WordPress, Contentful y Drupal hacia el mundo impulsado por GROQ de Sanity. Voy a ser franco sobre dónde brilla Sanity, dónde te frustrarás, y cuáles son los cronogramas reales.

Tabla de Contenidos

Sanity Migration Playbook: Moving from WordPress, Contentful, or Drupal

Por Qué los Equipos Se Están Moviendo a Sanity en 2025

Saquemos de en medio lo obvio. La edición colaborativa en tiempo real de Sanity, su Studio personalizable, y el enfoque de contenido estructurado son genuinamente buenos. Pero la razón por la que la mayoría de los equipos se comunican con nosotros sobre la migración no es porque hayan leído un artículo de blog sobre las características de Sanity. Es porque algo se rompió.

Los sitios de WordPress llegan a límites de escalabilidad alrededor de 50,000+ piezas de contenido con tipos de publicación personalizados complejos. El modelo de precios de Contentful comienza a apretar en el nivel empresarial — hemos visto equipos enfrentándose a facturas de $3,500+/mes por lo que equivale a una API de contenido. Los equipos de Drupal no pueden encontrar desarrolladores más, al menos no los que quieren trabajar con plantillas PHP en 2025.

El modelo de precios de Sanity es genuinamente más predecible para la mayoría de los equipos. El nivel gratuito cubre hasta 100K solicitudes API/mes y 500K activos. El plan Growth a $99/mes/proyecto te obtiene 2.5M solicitudes API y 1M activos. Para comparar, el plan Team de Contentful corre a $300/mes y el nivel Premium de Contentful puede fácilmente exceder $2,000/mes.

Pero aquí está mi opinión honesta: si tu CMS actual está funcionando bien y tu equipo es productivo, no migres solo porque Sanity sea más nuevo o más cool. Las migraciones siempre cuestan más de lo que piensas.

Auditoría Pre-Migración: El Paso que Todos Omiten

Antes de escribir una sola línea de código de migración, necesitas una auditoría de contenido. No un escaneo rápido — una auditoría real. Así es como se ve:

Inventario de Contenido

Documenta cada tipo de contenido, cada campo, cada relación. Utilizo una hoja de cálculo con estas columnas:

  • Nombre del tipo de contenido
  • Total de elementos
  • Campos (con tipos)
  • Relaciones con otros tipos de contenido
  • Archivos adjuntos multimedia (cantidad y tamaño total)
  • Funcionalidad personalizada (códigos cortos, widgets, incrustaciones)
  • Fecha de última modificación
  • ¿Aún relevante? (Sí/No/Tal vez)

Te sorprenderá cuánto contenido es peso muerto. En una migración de WordPress, un cliente tenía 12,000 publicaciones. Después de la auditoría, solo 4,200 eran aún relevantes. Eso es 65% menos contenido para migrar, probar y validar.

Mapeo de Dependencias Técnicas

Lista todos los plugins, módulos o integraciones que tu CMS actual utiliza. Para cada uno, determina:

  1. ¿Sanity puede manejar esto de forma nativa?
  2. ¿Hay un plugin de Sanity para esto?
  3. ¿Necesitamos construir una solución personalizada?
  4. ¿Podemos descartar esto completamente?

Este mapeo solo te ahorrará semanas de sorpresas en el camino.

Evaluación de Preparación del Equipo

Sanity Studio está basado en React. Tus editores de contenido necesitarán capacitación. Tus desarrolladores necesitarán aprender GROQ (o usar GraphQL, aunque GROQ es donde Sanity realmente brilla). Presupuesta 1-2 semanas para la incorporación del equipo — no como un elemento deseado, sino como un elemento de línea.

Migración de WordPress a Sanity

WordPress es el CMS de origen más común del que migramos. También es el más complicado, porque WordPress no es solo un CMS — es toda una plataforma de aplicación a la que la gente ha añadido de todo.

Lo Que Se Transfiere Limpiamente

  • Publicaciones y páginas (contenido básico)
  • Categorías y etiquetas
  • Imágenes destacadas
  • Datos de autor
  • Campos personalizados básicos (ACF, Meta Box)

Lo Que Se Vuelve Complicado

  • Bloques Gutenberg: Cada tipo de bloque necesita un bloque personalizado correspondiente de Portable Text o un tipo de objeto en Sanity. Si tienes 15+ bloques Gutenberg personalizados, presupuesta tiempo significativo aquí.
  • Códigos cortos: Necesitan ser analizados, interpretados y convertidos a anotaciones Portable Text o bloques personalizados. Los códigos cortos de WPBakery y Elementor son particularmente dolorosos.
  • Contenido generado por plugins: Productos de WooCommerce, datos de Yoast SEO, campos repetidores de ACF — cada uno requiere lógica de migración personalizada.
  • Biblioteca multimedia: WordPress almacena múltiples tamaños de imagen. Sanity maneja transformaciones de imagen sobre la marcha, así que solo necesitas los originales. Pero ¿encontrar los originales en una carpeta wp-uploads desordenada? Divertido.

Enfoque de Script de Migración

Típicamente utilizo un script Node.js que accede a la API REST de WordPress y escribe en la API de mutación de Sanity:

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 requires HTML-to-Portable-Text conversion
      body: await convertToPortableText(post.content.rendered),
    })
  }

  await transaction.commit()
  console.log(`Migrated page ${page} of ${totalPages}`)

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

La función convertToPortableText es donde vive el 80% de la complejidad. Utilizo el paquete @sanity/block-tools combinado con jsdom para análisis HTML. Maneja HTML básico bien, pero elementos personalizados y códigos cortos necesitan manejadores individuales.

Cronograma Realista

Para un sitio WordPress típico con 500-2,000 publicaciones, campos personalizados estándar, y un puñado de tipos de publicación personalizados: 4-8 semanas incluyendo modelado de contenido, escritura de scripts de migración, validación de datos, y capacitación de editores.

Sanity Migration Playbook: Moving from WordPress, Contentful, or Drupal - architecture

Migración de Contentful a Sanity

Contentful-a-Sanity es en realidad la ruta de migración más suave de las tres. ¿Por qué? Porque ambas son plataformas de contenido estructurado con modelos mentales similares. Tu contenido ya está en un CMS headless con tipos de contenido y campos definidos.

Diferencias Clave a Considerar

Característica Contentful Sanity
Texto enriquecido Rich Text (basado en JSON) Portable Text (basado en JSON)
Modelado de contenido Interfaz web Esquemas definidos en código
Lenguaje de consulta GraphQL / REST GROQ (+ GraphQL)
Localización Integrada a nivel de campo Plugin o personalizada
Referencias Enlaces (Entry/Asset) Referencias con tipos
Webhooks
Manejo de activos CDN integrado CDN Sanity + hotspot/crop
Precios (nivel medio) ~$300/mes (Team) $99/mes (Growth)

Conversión de Texto Enriquecido

El Rich Text de Contentful y el Portable Text de Sanity son ambos basados en JSON, lo cual es excelente. Pero tienen estructuras diferentes. Necesitarás escribir un transformador:

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':
        // Map to your custom Portable Text type
        return mapEmbeddedEntry(node)
      // ... handle all node types
    }
  }).filter(Boolean)
}

Mapeo de Tipo de Contenido a Esquema

Los tipos de contenido de Contentful se mapean bastante directamente a tipos de documento y objeto de Sanity. El mayor cambio es que los esquemas de Sanity se definen en código (JavaScript/TypeScript), no en una interfaz web. Esto es en realidad una ventaja enorme — tu modelo de contenido vive en control de versiones.

Utiliza la API de Gestión de Contentful para exportar tu modelo de contenido, luego escribe un script que genere archivos de esquema de Sanity:

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

Cronograma Realista

Para un espacio de Contentful con 10-20 tipos de contenido y 5,000-10,000 entradas: 3-5 semanas. Es más rápido porque ya estás pensando en contenido estructurado.

Migración de Drupal a Sanity

Las migraciones de Drupal son las que me hacen servir un segundo café. No porque Drupal sea malo — es un sistema poderoso. Pero los sitios de Drupal tienden a ser antiguos, personalizados al máximo, y funcionando en infraestructura que nadie entiende completamente.

Los Desafíos Específicos de Drupal

  • Tipos de contenido con 50+ campos: Drupal facilita agregar campos. Demasiado fácil. He visto tipos de contenido con 80 campos, la mitad de los cuales están sin usar.
  • Referencias de términos de taxonomía: El sistema de taxonomía de Drupal es flexible pero puede crear jerarquías profundamente anidadas que necesitan aplanarse para Sanity.
  • Módulo de párrafos: Si el sitio usa Párrafos de Drupal (y la mayoría de los sitios modernos de Drupal lo hacen), cada tipo de párrafo se convierte en un tipo de bloque Portable Text o un objeto Sanity. Esta es la tarea individual más grande.
  • Entidades multimedia: El sistema de medios de Drupal 9/10 es más complejo que el de WordPress. Múltiples tipos de medios, entidades de medios reutilizables, y configuraciones de campo de archivo todo necesita mapeo.
  • Contenido multilingüe: El sistema de traducción de Drupal es sofisticado. Sanity no tiene localización integrada en el mismo nivel — necesitarás el plugin @sanity/document-internationalization o un enfoque a nivel de campo.

Enfoque de Migración

Prefiero usar el módulo JSON:API de Drupal (incluido en Drupal core desde 9.x) como la capa de extracción:

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()
}

Para sitios Drupal 7 más antiguos sin JSON:API, podrías necesitar consultar la base de datos directamente. El esquema de base de datos de Drupal 7 es... una experiencia. Las tablas field_data_* te perseguirán en tus sueños.

Cronograma Realista

Las migraciones de Drupal varían enormemente. Un sitio Drupal 10 directo con 5-10 tipos de contenido: 5-8 semanas. Un sitio Drupal 7 heredado con 30+ tipos de contenido, Párrafos, y contenido multilingüe: 8-16 semanas. No estoy exagerando.

Modelado de Contenido: Acertando en tus Esquemas

Aquí está la cosa que la mayoría de guías de migración no te dirán: no repliques tu modelo de contenido antiguo en Sanity. Esta es tu oportunidad para arreglar años de deuda de contenido acumulada.

Errores Comunes de Modelado

  1. Crear un mapeo de campo 1:1: Solo porque WordPress tenía un campo personalizado "subtítulo" no significa que Sanity necesite uno. Tal vez debería ser parte de un objeto "hero" estructurado.
  2. Anidar objetos en exceso: Sanity te permite anidar objetos profundamente. Resiste la tentación. Los esquemas más bien planos son más fáciles de consultar con GROQ y más fáciles para que los editores trabajen.
  3. Ignorar el poder de Portable Text: No simplemente viertas HTML en un único campo de texto. Diseña tipos de bloque personalizados que coincidan con tus patrones de contenido. Un bloque "callout", un bloque "code snippet", un bloque "image with caption" — estos hacen la vida de los editores mejor.

Proceso de Diseño de Esquema

Sigo este orden:

  1. Auditar contenido existente (hecho en pre-migración)
  2. Identificar los patrones de contenido reales (no lo que el CMS impuso)
  3. Diseñar esquemas en papel/pizarra primero
  4. Construir esquemas en código
  5. Importar un pequeño lote de prueba (50-100 elementos)
  6. Tener editores prueben la experiencia de Studio
  7. Iterar sobre esquemas antes de la migración completa

Los pasos 5-7 son críticos y a menudo se omiten. Hemos escrito más sobre enfoques de modelado de contenido en nuestro trabajo de desarrollo de CMS headless.

Estrategias y Herramientas de Migración de Datos

Herramientas Esenciales

  • @sanity/client: El cliente oficial de JavaScript para leer/escribir datos de Sanity
  • @sanity/block-tools: Convierte HTML a Portable Text
  • sanity dataset import/export: Herramientas CLI para operaciones de conjunto de datos completo
  • ndjson: Sanity utiliza JSON delimitado por saltos de línea para importaciones — familiarízate con esto
  • jsdom o htmlparser2: Para análisis HTML durante la conversión de texto enriquecido

Arquitectura de Migración

Estructuro cada migración como una tubería con cuatro etapas:

Extrae → Transforma → Carga → Valida

Cada etapa es un script separado. Esto importa porque ejecutarás la migración varias veces — típicamente 5-10 veces antes de la ejecución final de producción. Tener etapas separadas significa que puedes re-ejecutar solo las partes que necesitan corrección.

# 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

Manejo de Activos

Las imágenes y archivos siempre son la parte más lenta. La tubería de activos de Sanity es buena, pero cargar 10,000 imágenes toma tiempo. Consejos:

  • Cargar activos primero, mantener un mapeo de URLs antiguas a IDs de activos nuevos de Sanity
  • Usar cargas concurrentes (pero respetar límites de velocidad — 25 req/seg para el plan Growth)
  • Verificar dimensiones de imagen y formatos antes de cargar
  • No migrar tamaños de miniaturas — Sanity genera estas sobre la marcha a través de su CDN de imagen

Los Costos Ocultos de los que Nadie Habla

Déjame ser franco contigo sobre costos que no aparecen en la estimación típica de migración.

Redirecciones de URL

Si estás cambiando tu frontend (que probablemente lo estés si estás pasando a un CMS headless), necesitas mapeo de redirecciones. Cada. Única. URL. Para SEO, esto es innegociable. Un sitio con 5,000 páginas necesita 5,000 reglas de redirección. Herramientas como redirecciones de next.config.js o archivo _redirects de Vercel pueden manejar esto, pero alguien tiene que construir el mapeo.

Migración de Metadatos SEO

Datos de Yoast SEO desde WordPress. Datos del módulo Metatag desde Drupal. Campos SEO de Contentful. Todo esto necesita venir. Títulos meta personalizados, descripciones, imágenes Open Graph, URLs canónicas, datos estructurados — es un proyecto dentro del proyecto.

Capacitación de Editores y Documentación

Presupuesta 2-4 días mínimo. Sanity Studio es intuitivo, pero es diferente de lo que tus editores conocen. Típicamente creamos documentación personalizada de Studio con capturas de pantalla y grabamos 3-5 videos de walkthrough.

Desarrollo Frontend

Este es el elefante en la sala. Migrar contenido a Sanity es solo la mitad del proyecto. También necesitas un frontend que consuma el contenido. Ya sea que estés usando Next.js, Astro, u otro framework, la construcción del frontend es a menudo 50-70% del costo total del proyecto. Revisa nuestro trabajo con Next.js y Astro si estás evaluando opciones de frontend.

Comparación de Cronograma y Presupuesto

Basado en proyectos completados en 2024-2025:

Ruta de Migración Volumen de Contenido Complejidad Cronograma Rango de Presupuesto
WordPress → Sanity < 1,000 páginas Baja 3-5 semanas $8K-$15K
WordPress → Sanity 1,000-10,000 páginas Media 6-10 semanas $15K-$35K
WordPress → Sanity 10,000+ páginas Alta 10-16 semanas $35K-$75K
Contentful → Sanity < 5,000 entradas Baja-Media 3-5 semanas $7K-$18K
Contentful → Sanity 5,000-20,000 entradas Media 5-8 semanas $18K-$40K
Drupal → Sanity < 2,000 nodos Media 5-8 semanas $12K-$25K
Drupal → Sanity 2,000-15,000 nodos Alta 8-14 semanas $25K-$60K
Drupal 7 → Sanity Cualquiera Muy Alta 10-20 semanas $35K-$90K

Nota: Estos rangos incluyen solo migración de contenido. Desarrollo frontend es adicional. Contáctanos en /pricing para estimaciones específicas del proyecto.

Estos números incluyen modelado de contenido, escritura de scripts de migración, validación de datos, y capacitación básica de editores. No incluyen desarrollo frontend, diseño, o mantenimiento continuo.

Lista de Verificación Post-Migración

Aquí está la lista de verificación que utilizo en cada migración:

  • Todos los tipos de contenido migrados y verificados
  • Todas las referencias/relaciones intactas
  • Todas las imágenes y archivos cargados y enlazados correctamente
  • Contenido de texto enriquecido renderizado correctamente (verifica formato roto)
  • Redirecciones de URL en su lugar y probadas
  • Metadatos SEO migrados (títulos, descripciones, datos OG)
  • Mapa del sitio XML regenerado
  • Consola de búsqueda actualizada con nuevo mapa del sitio
  • Seguimiento de analítica preservado
  • Cuentas de editor creadas y permisos establecidos
  • Capacitación de editor completada
  • Vista previa de contenido (modo borrador) funcionando
  • Webhooks configurados para disparadores de compilación
  • Copia de seguridad de datos del CMS de origen archivada
  • Cambios de DNS planeados (si aplica)
  • Línea de base de rendimiento medida
  • Monitoreo de 404 configurado para los primeros 30 días

Ese último punto es importante. Sin importar cuán exhaustivo sea tu mapeo de redirecciones, algunas URLs se escaparán. Monitorea tus 404s agresivamente durante el primer mes.

Preguntas Frecuentes

¿Cuánto tiempo toma una migración típica de WordPress a Sanity? Para un sitio WordPress estándar con menos de 2,000 publicaciones y campos personalizados directos, espera 4-8 semanas. Eso incluye modelado de contenido, escritura de scripts de migración, validación de datos, y capacitación de editores. Los sitios con bloques Gutenberg complejos, WooCommerce, o contenido multilingüe pueden tomar 10-16 semanas. El volumen de contenido importa menos que la complejidad de tus tipos de contenido.

¿Puedo migrar de Contentful a Sanity sin perder datos? Sí, y es en realidad la ruta de migración más limpia de las tres que cubro aquí. Ambas plataformas usan contenido estructurado basado en JSON así que el mapeo es relativamente directo. El texto enriquecido necesita conversión del formato de Contentful a Portable Text, y las referencias necesitan remapeo, pero no deberías perder ningún dato. Recomiendo ejecutar la migración contra un conjunto de datos staging primero y hacer una comparación exhaustiva de contenido antes de cambiar.

¿Qué sucede con mis clasificaciones de SEO durante una migración de CMS? Esta es la pregunta que mantiene despiertos a los directores de marketing por la noche. Si manejas redirecciones apropiadamente, mantienes tu estructura de URL donde sea posible, y migras todos los metadatos de SEO, deberías ver impacto mínimo. La documentación propia de Google dice que migraciones adecuadamente redirigidas pueden ver una caída temporal de 2-4 semanas antes de recuperarse. La palabra clave es "adecuadamente". Omite el mapeo de redirecciones y hundirás tus clasificaciones. Lo hemos visto suceder.

¿Es Sanity más barato que Contentful para uso empresarial? En la mayoría de los casos, sí — a veces significativamente. El plan Growth de Sanity a $99/mes cubre lo que necesitarías del plan Team de Contentful a $300/mes. A escala empresarial, la diferencia se hace más grande. Los precios Premium de Contentful no son públicos pero típicamente corren $2,000-$4,000+/mes. Los precios Enterprise de Sanity tampoco son públicos pero generalmente salen más bajos para uso equivalente. La diferencia de costo real está en las llamadas API — los límites incluidos de Sanity son más generosos.

¿Debo migrar mi sitio Drupal 7 a Sanity o actualizar primero a Drupal 10? Ve directamente a Sanity. Migrar de Drupal 7 a Drupal 10 es casi tanto trabajo como migrar a un CMS diferente completamente — la arquitectura cambió tan dramáticamente entre versiones. Si ya estás invirtiendo en una migración mayor, podrías también moverte a la plataforma que realmente quieres estar a largo plazo. La única excepción: si tu equipo está profundamente invertido en el ecosistema de Drupal y solo quiere modernizarse, Drupal 10 con un frontend headless es una ruta válida.

¿Necesito reconstruir mi frontend cuando migro a Sanity? Si vienes de un CMS monolítico como WordPress o Drupal, sí — necesitarás un nuevo frontend ya que Sanity es headless. Esta es generalmente la parte más grande del proyecto. Si vienes de Contentful, a menudo puedes reutilizar tu frontend existente con llamadas API modificadas, especialmente si ya estás usando Next.js u un framework similar. Manejamos tanto la migración del CMS como construcciones frontend como proyectos integrados.

¿Puedo ejecutar mi CMS antiguo y Sanity en paralelo durante la migración? Absolutamente, y lo recomiendo. Ejecuta ambos sistemas durante 2-4 semanas después de tu migración inicial. Los editores pueden continuar trabajando en el CMS antiguo mientras validas datos en Sanity. Solo congela contenido en el sistema antiguo antes de tu ejecución de migración final — no quieres perseguir un objetivo en movimiento. Algunos equipos establecen una fecha de "congelación de contenido" 48 horas antes del cambio final.

¿Cuál es el error más grande que los equipos cometen durante una migración de Sanity? Intentar replicar su estructura de CMS antiguo exactamente en Sanity. Veo esto constantemente. Los equipos vienen de WordPress e intentan construir esquemas moldeados por WordPress en Sanity — tipos de "página" genéricos con disposiciones flexibles en lugar de tipos de contenido construidos para el propósito. La fortaleza de Sanity es contenido estructurado. Usa la migración como una oportunidad para modelar tu contenido apropiadamente. Dedica una semana extra al modelado de contenido. Te ahorrará meses de dolor después. Si quieres orientación en esto, contáctanos — el modelado de contenido es una de las cosas en las que pasamos más tiempo en proyectos de migración.