tva
← Insights

Migración de WordPress a Astro: Una Guía Práctica

Migrar un blog de WordPress a Astro es un proyecto técnico con múltiples partes interconectadas: extracción de contenido, transformación, enrutamiento URL, SEO y despliegue. Cada parte tiene sus propias trampas. Este artículo cubre el proceso completo que utilizamos para migrar un blog con más de cien publicaciones, incluyendo las herramientas, los scripts y las decisiones que tomamos a lo largo del camino.


Por Qué Cambiar

WordPress funciona. Para una gran cantidad de casos de uso, es la herramienta correcta. Para un blog técnico con requisitos de rendimiento estrictos, control total sobre el HTML de salida y un equipo que se siente cómodo con JavaScript moderno, Astro es una mejor opción.

El problema concreto que estábamos resolviendo: el sitio de WordPress estaba en una instancia compartida con tiempos de carga lentos, dependía de plugins para características básicas que preferimos controlar directamente, y la interfaz de edición era más torpe de lo necesario para contenido que principalmente se escribe en texto plano.

Astro resuelve estos problemas: genera HTML estático, no tiene tiempo de ejecución en el servidor, y puede usarse con cualquier editor de texto plano para archivos Markdown. La compensación es que las funciones dinámicas requieren más trabajo deliberado. Para un blog, esa compensación funciona bien.

Extracción de Contenido

El punto de partida es la exportación XML de WordPress. WordPress tiene una exportación integrada en Herramientas → Exportar que produce un archivo XML con todo el contenido del post. Para un sitio con mucho contenido, esto puede ser un archivo grande, pero es manejable.

El XML exportado contiene los posts en formato HTML como fueron almacenados en la base de datos de WordPress —no Markdown, no texto plano. El primer paso es convertir ese HTML a Markdown para que sea editable como archivos de contenido de Astro.

Utilizamos wordpress-export-to-markdown, una herramienta de línea de comandos de Node.js que toma el XML exportado y produce archivos Markdown con frontmatter:

npx wordpress-export-to-markdown --post-folders=true --include-other-types=true

La herramienta hace un buen trabajo con la estructura básica: encabezados, párrafos, listas, bloques de código. Las características específicas de WordPress —bloques Gutenberg complejos, shortcodes, galerías— requieren revisión manual. Esperábamos eso y construimos tiempo de revisión en el proceso.

Estructura de Rutas URL

La preservación de las URL es crítica para el SEO. Si el sitio de WordPress usa /blog/post-slug/ y el sitio de Astro usa /posts/post-slug, cualquier backlink existente se rompe y el PageRank acumulado se pierde. Las redirecciones pueden mitigar esto, pero la correspondencia exacta de URL es preferible cuando sea posible.

Astro enruta basándose en la estructura de archivos. Un archivo en src/pages/blog/[slug].astro maneja rutas en /blog/[slug]. Configuramos la estructura de directorios de Astro para que coincida con las URL de WordPress exactamente.

Para URLs que no podían coincidir exactamente —por ejemplo, WordPress usa barras diagonales finales y el generador de sitios estáticos no— configuramos redirecciones en el nivel del servidor web. En Nginx:

rewrite ^/(.+)/$ /$1 permanent;

Frontmatter y Metadatos

Los posts de Astro con frontmatter YAML llevan metadatos directamente en el archivo. El frontmatter mínimo que necesitábamos para cada post:

---
title: "Título del Post"
date: 2024-01-15
slug: post-slug
excerpt: "Descripción breve para SEO y vistas de lista."
---

La herramienta de exportación de WordPress generó la mayor parte de esto automáticamente. Añadimos el campo excerpt manualmente revisando cada post, ya que WordPress almacena los extractos por separado y no siempre de manera consistente.

Imágenes

Las imágenes son la parte más trabajosa de cualquier migración de WordPress. WordPress almacena imágenes en wp-content/uploads/ con un esquema de organización por año y mes. Los posts hacen referencia a las imágenes con URLs absolutas apuntando al dominio de WordPress.

Descargamos todas las imágenes usando wget con el XML exportado como fuente de URLs, luego actualizamos las referencias de imágenes en los archivos Markdown para usar rutas relativas. Un script Python manejó la actualización de URL de imagen a granel:

import re, os

def update_image_urls(content, post_slug):
    pattern = r'https://olddomain\.com/wp-content/uploads/[^\s)"]+'
    def replace(match):
        filename = match.group(0).split('/')[-1]
        return f'/images/posts/{post_slug}/{filename}'
    return re.sub(pattern, replace, content)

Integración de Búsqueda

WordPress tiene integración de búsqueda integrada. Astro no lo tiene —es un generador de sitios estáticos y no tiene un proceso de servidor para manejar consultas de búsqueda. La búsqueda en el lado del cliente usando Pagefind es el enfoque más sencillo que funciona bien para sitios de tamaño de blog.

Pagefind se ejecuta como paso de compilación después de Astro, indexa el HTML generado, y produce un índice de búsqueda estático que la biblioteca de JavaScript del lado del cliente consulta sin hacer solicitudes de servidor. La adición al proceso de compilación:

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  integrations: [],
  // Pagefind se ejecuta en postbuild via package.json
});
// package.json
{
  "scripts": {
    "build": "astro build && npx pagefind --source dist"
  }
}

Feed RSS

WordPress genera feeds RSS automáticamente. En Astro, el feed RSS se genera como un archivo estático durante la compilación. La integración @astrojs/rss maneja esto:

// src/pages/rss.xml.js
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET(context) {
  const posts = await getCollection('blog');
  return rss({
    title: 'Título del Blog',
    description: 'Descripción del Blog',
    site: context.site,
    items: posts.map(post => ({
      title: post.data.title,
      pubDate: post.data.date,
      description: post.data.excerpt,
      link: `/blog/${post.slug}/`,
    })),
  });
}

Verificación de SEO Post-Migración

Después de lanzar, verificamos que Google Search Console siguiera reconociendo el sitio correctamente, que el mapa del sitio se enviara y se indexara, y que no hubiera errores 404 inesperados en el rastreo. Monitorear los cambios de posición de búsqueda durante las primeras cuatro semanas después de la migración es estándar —algo de fluctuación es normal, y las caídas importantes señalan URLs faltantes o problemas de redireccionamiento.

La migración en general fue exitosa. El rendimiento del sitio mejoró significativamente, el flujo de trabajo de publicación es más sencillo, y tenemos control total sobre el HTML de salida. Las partes de trabajo intensivo —revisión de imágenes, revisión de extractos, verificación de URL— tomaron más tiempo del esperado, pero no encontramos problemas de migración fundamentales.

Artículos relacionados