logo

Headless WordPress: Una solución sencilla para integrar Yoast SEO Sitemap con NextJS

09 octubre 2023

Índice de contenidos

Introducción

Podrías encontrar diferentes soluciones para proporcionar el contenido de sitemap.xml en NextJS, la manera más obvia sería seguir los pasos recomendados en la propia documentación de NextJS.

En WordPress, tenemos la posibilidad de instalar un plugin que genera automáticamente un archivo sitemap.xml, pero esto no funcionaría de por sí con una arquitectura Headless sin hacer algunos cambios en nuestro código. En este caso voy a usar el plugin SEO Yoast para WordPress.

Si has buscado alguna solución para integrarlo con NextJS probablemente has encontrado multitud de ellas en las cuales se requiere hacer fetch requests, instalar dependencias, crear un proxy, etc.
Pues bien, puede ser mucho más sencillo que todo eso, así que te recomiendo seguir leyendo, vamos a ello!

Nota: Esta solución está inspirada en la integración aplicada en HeadstartWP, un framework creado por 10up como punto de partida para crear Headless con WordPress y NextJS usando la REST API.

Configuración en NextJS

NextJS nos ofrece la posibilidad de añadir rewrites a nuestro archivo nextjs.config.js de una manera sencilla donde el propio NextJS se encarga de hacer toda la magia por nosotros.

Básicamente, un rewrite (reescritura) permite mapear una ruta de solicitud entrante a una ruta de destino diferente sin que el usuario se dé cuenta. No hay que confundirlo con una redirección, la cual envía al usuario a una página diferente; el usuario ve que la URL en el navegador ha cambiado. Por el contrario, con un rewrite, la URL en el navegador no cambia, aunque se muestra el contenido de un destino diferente.

Por lo tanto le diremos a NextJS que cuando el navegador haga una petición para obtener el sitemap.xml debe servir el contenido que proviene del sitemap proporcionado por Yoast en WordPress.

Añadiremos al archivo nextjs.config.js la siguiente configuración:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async rewrites() {
    return [
      {
        source: '/sitemap.xml',
        destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/sitemap_index.xml`,
      },
      {
        source: '/:sitemap(.*sitemap.*\.xml)',
        destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/:sitemap`,
      },
      {
        source: '/:path(.*main-sitemap\.xsl)',
        destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/:path`,
      },
    ]
  },

Donde process.env.NEXT_PUBLIC_SOURCE_URL es la «environment variable» (variable de entorno) que indica cual es la URL de nuestro sitio WordPress.

Explicación:
Hemos añadido 3 rewrites:

El primero:

1
2
3
4
{
   source: '/sitemap.xml',
   destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/sitemap_index.xml`,
}

Para el sitemap general de Yoast, el punto de partida de los diferentes sitemaps.
Yoast redirige sitemap.xml a sitemap_index.xml por defecto, así que directamente le decimos a NextJS que el contenido debe venir de sitemap_index.xml para ahorrarnos un redirect.

El segundo:

1
2
3
4
{
   source: '/:sitemap(.*sitemap.*\.xml)',
   destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/:path`,
}

Para los sitemaps posteriores para cada tipo de contenido y taxonomías. El plugin de Yoast genera diferentes xml para los diferentes tipos de contenido y taxonomías, por ejemplo:

/post-sitemap.xml
/page-sitemap.xml
/category-sitemap.xml
/post_tag-sitemap.xml

El tercero:

1
2
3
4
{
   source: '/:path(.*main-sitemap\.xsl)',
   destination: `${process.env.NEXT_PUBLIC_SOURCE_URL}/:path`,
}

Yoast incluye su hoja de estilos en el sitemap.xml, sin este rewrite nos encontramos con un error de CPS/CORS (Política de Seguridad del Contenido y Recursos de Origen Cruzado) ya que el dominio de nuestro sitio WordPress y nuestro Front End son distintos. Este rewrite resuelve este error parcialmente ya que necesitaremos hacer algunos cambios en WordPress, que detallaré más abajo en este post, para cambiar la URL de main-sitemap.xsl generada por Yoast para que apunte al dominio del Front End.

Configuración en WordPress para SEO Yoast

Desde WordPress, en primer lugar necesitamos solventar el error mencionado anteriormente con CPS/CORS con la hoja de estilos de Yoast y en segundo lugar reemplazar el dominio de WordPress con el dominio del sitio NextJS en los enlaces generados por Yoast en los xml.

Para solucionar el error con CPS/CORS deberemos filtrar la URL de la hoja de estilos incluida por Yoast en el xml del sitemap con el hook wpseo_stylesheet_url para reemplazar el dominio WordPress con el dominio de la web en NextJS.

1
2
3
4
5
add_filter( 'wpseo_stylesheet_url', 'filter_wpseo_stylesheet_url', 10, 1 );

function filter_wpseo_stylesheet_url( $stylesheet ) {
   return '<?xml-stylesheet type="text/xsl" href="https://mi-dominio.com/wp-content/plugins/wordpress-seo/css/main-sitemap.xsl"?>';
}

Reemplaza mi-dominio.com con el dominio de tu sitio web en NextJS.

Por último necesitaremos filtrar las URLs incluidas en el sitemap, ya que Yoast SEO genera el sitemap apuntando al dominio WordPress. Lo haremos con los hooks:

wpseo_sitemap_index_links que modificará las URLs en el archivo principal sitemap.xml donde se encuentran listados los demás enlaces a los xml de los sitemaps de los diferentes tipos de contenido y taxonomías.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
add_filter( 'wpseo_sitemap_index_links', 'filter_sitemap_index_links', 10, 1 );

function filter_sitemap_index_links( $links ) {
	foreach ( $links as $key => $link ) {
		if ( empty( $link['loc'] ) ) {
			continue;
		}

		$links[$key]['loc'] = str_replace(
			get_home_url(),
			'https://mi-dominio.com',
			$link['loc']
		);
	}

	return $links;
}

wpseo_sitemap_url que modificará las URLs que se encuentran dentro de esos xml para los diferentes tipos de contenido y taxonomías, como /post-sitemap.xml o /page-sitemap.xml

1
2
3
4
5
6
7
8
9
add_filter( 'wpseo_sitemap_url', 'filter_sitemap_url', 10, 1 );

function filter_sitemap_url( $output ) {
	return str_replace(
		get_home_url(), 
		'https://mi-dominio.com',
		$output
	);
}

Y así de fácil ya tenemos nuestro sitemap.xml generado por Yoast SEO servido a través de nuestro sitio web en NextJS.