Contents
Introducción
En SEO, la etiqueta rel=canonical indica a los motores de búsqueda cuál es la URL canónica (preferida) para una página concreta, evitando problemas de contenido duplicado y consolidando señales de enlace. WordPress añade una canonical por defecto en muchas instalaciones, pero en entornos con contenido personalizado, paginación avanzada, parámetros, taxonomías o búsquedas, a menudo conviene generar y normalizar manualmente la URL canonical mediante PHP.
Objetivos de este tutorial
- Explicar cuándo y por qué añadir una canonical personalizada en WordPress.
- Proveer un ejemplo simple y un ejemplo avanzado (cubriendo singulars, taxonomías, archivos, paginación, attachments y parámetros).
- Mostrar cómo evitar conflictos con plugins SEO (Yoast, Rank Math) y cómo normalizar urls (https, www, trailing slash, parámetros de tracking).
Conceptos clave y buenas prácticas
- Canonical por defecto: WordPress core tiene una función rel_canonical() que se engancha a wp_head. En muchos casos basta con esto, pero cuando necesitas control total conviene reemplazarla.
- Normalización: Decide una única forma de URL (https vs http, www vs no-www, trailing slash) y asegúrate de que la canonical la refleje.
- Paginación: Puedes apuntar la canonical a la propia URL paginada (recomendado por muchos desarrolladores hoy) o al primer volumen lo importante es ser consistente y usar rel=prev/next si corresponde.
- Parametros: Quitar parámetros de tracking (utm_) de la canonical para no crear duplicados.
- Compatibilidad con plugins SEO: No dupliques etiquetas si Yoast/RankMath ya generan la canonical detecta y evita añadir otra.
Lista rápida de funciones útiles de WordPress
Condición | Función para obtener URL |
---|---|
Entrada/Página/CPT | get_permalink() |
Home / Front page | home_url(/) |
Archivo de taxonomy | get_term_link() |
Archivo de post type | get_post_type_archive_link() |
Autor | get_author_posts_url() |
Paginas con paginación | get_pagenum_link() |
Quitar parámetros | remove_query_arg() |
Implementación: Ejemplo simple
Esta primera versión cubre los casos más comunes: singulares, home, taxonomías y autor. También elimina parámetros UTM y normaliza con user_trailingslashit.
ID ) } elseif ( is_front_page() is_home() ) { canonical = home_url( / ) } elseif ( is_category() is_tag() is_tax() ) { term = get_queried_object() canonical = get_term_link( term ) } elseif ( is_author() ) { author = get_queried_object() canonical = get_author_posts_url( author->ID ) } else { // Fallback a la URL actual canonical = home_url( add_query_arg( NULL, NULL ) ) } // Quitar parámetros comunes de tracking canonical = remove_query_arg( array( utm_source, utm_medium, utm_campaign, utm_term, utm_content ), canonical ) // Normalizar trailing slash según la instalación canonical = user_trailingslashit( canonical ) echo n } ?>
Notas sobre este ejemplo
- remove_action() evita que WordPress inyecte su canonical por defecto si quieres la tuya.
- La detección de plugins es básica (WPSEO_VERSION para Yoast y la existencia de la clase RankMathPlugin para Rank Math). Si tu plugin SEO es otro, añade su comprobación.
Implementación avanzada: cubrir paginación, attachments, parámetros dinámicos y normalización HTTPS/WWW
El siguiente ejemplo es robusto: maneja paginación (opción para canonical a self o al first page), attachments (canonical a parent o a sí misma si no hay parent), taxonomías, archives de CPT, autor, búsqueda y 404 y normaliza parámetros y esquemas.
post_parent ) { canonical = get_permalink( post->post_parent ) } else { canonical = get_permalink( post->ID ) } } else { canonical = get_permalink( post->ID ) } } elseif ( is_front_page() is_home() ) { canonical = home_url( / ) } elseif ( is_category() is_tag() is_tax() ) { term = get_queried_object() canonical = get_term_link( term ) } elseif ( is_post_type_archive() ) { post_type = get_query_var( post_type ) canonical = get_post_type_archive_link( post_type ) } elseif ( is_author() ) { author = get_queried_object() canonical = get_author_posts_url( author->ID ) } elseif ( is_search() ) { // Opcional: decidir si indexas búsquedas. Frecuente: noindex evitar canonical. // Si quieres canonicalizar búsquedas a home o a sí misma, ajusta aquí. return } else { // Fallback a la URL actual canonical = home_url( add_query_arg( NULL, NULL ) ) } // Paginación: decidir política paged = get_query_var( paged ) ? intval( get_query_var( paged ) ) : 0 use_self_for_paged = true // si true -> cada página paginada se canonicaliza a sí misma if ( paged > 1 ) { if ( use_self_for_paged ) { canonical = get_pagenum_link( paged ) } else { // canonical al primer volumen (sin paginación) if ( is_singular() ) { canonical = get_permalink() } else { // para archives usa la versión sin paged canonical = remove_query_arg( paged, canonical ) } } } // Quitar parámetros de tracking y algunos parámetros innecesarios canonical = remove_query_arg( array( utm_source, utm_medium, utm_campaign, utm_term, utm_content, fbclid ), canonical ) // Forzar https y/o no-www si tu sitio está configurado así. Ejemplo: forzar scheme y host de home_url() home = parse_url( home_url( / ) ) parsed = wp_parse_url( canonical ) if ( isset( home[scheme] ) isset( home[host] ) ) { parsed[scheme] = home[scheme] parsed[host] = home[host] } // Reconstruir la URL normalizada norm = ( isset( parsed[scheme] ) ? parsed[scheme] . :// : ) . ( isset( parsed[host] ) ? parsed[host] : ) . ( isset( parsed[path] ) ? parsed[path] : ) . ( isset( parsed[query] ) ? ? . parsed[query] : ) . ( isset( parsed[fragment] ) ? # . parsed[fragment] : ) // Aplicar trailing slash según la configuración de WP norm = user_trailingslashit( norm ) echo n } ?>
Explicaciones importantes del ejemplo avanzado
- get_pagenum_link() devuelve la URL correcta para páginas paginadas y respeta la estructura de enlaces permanentes.
- remove_query_arg() elimina parámetros de tracking que no aportan significado al contenido.
- El bloque que fuerza scheme/host al valor de home_url() evita inconsistencias entre http/https o www/no-www en la canonical.
- La variable use_self_for_paged te permite elegir la estrategia de paginación la documentación de Google ha variado con el tiempo, pero lo más importante es ser consistente y no generar duplicados.
Compatibilidad con plugins SEO
Si tu sitio usa Yoast SEO, Rank Math u otros plugins, normalmente éstos ya generan la etiqueta canonical (y añaden otras metaetiquetas importantes). Recomendación:
- Comprobar si el plugin ya añade canonical. Si es así, no añadir una segunda etiqueta para evitar duplicados.
- Si el plugin lo genera pero quieres customizar sólo ciertos casos, detecta la presencia del plugin y aplica tu lógica sólo cuando sea necesario.
- Para Yoast puedes comprobar defined(WPSEO_VERSION) o la existencia de funciones/clases propias. Para Rank Math, la existencia de la clase RankMathPlugin.
Pruebas y verificación
- Inspeccionar el código fuente en el front (ctrl U) y comprobar que sólo hay una etiqueta rel=canonical y que su href coincide con la URL normalizada deseada.
- Probar tipos de páginas: home, posts, páginas, attachments, categorías, etiquetas, taxonomías personalizadas, archivos de post type, autor, búsqueda, 404, y páginas paginadas.
- Verificar con la Google Search Console (inspección de URLs) y herramientas de crawling (Screaming Frog, Sitebulb) que las canonicales se leen correctamente.
- Comprobar redirecciones y versiones www/no-www y https para que la canonical coincida con la versión que devuelve 200 y no con la que redirige.
Errores y problemas comunes
- Añadir múltiples canonicales (core plugin tu código). Evitar duplicados detectando plugins o no llamando a remove_action si confías en Core/plugin.
- Canonical que apunta a la página 1 desde todas las páginas paginadas, provocando pérdida de indexación de contenido paginado si no se usa rel=prev/next correctamente.
- Dejar parámetros de tracking en la canonical (utm_, fbclid) creando URLs distintas para el mismo contenido.
- Canonical a una URL que devuelve redirección en lugar de 200 — siempre canonicalizar a la URL final (200).
Resumen / Checklist de implementación
- Decide si usarás la canonical que genera WordPress core, un plugin SEO o tu propio código.
- Si implementas tu propia canonical, elimina la que no quieras (remove_action) para evitar duplicados.
- Gestiona casos: singular, attachment, taxonomy, author, archives y paginación.
- Quita parámetros de tracking y normaliza esquema/host/trailing-slash.
- Comprueba compatibilidad con Yoast/RankMath antes de inyectar tu etiqueta.
- Verifica con herramientas y Google Search Console.
Enlaces útiles
Conclusión
Implementar una etiqueta rel=canonical correcta en WordPress con PHP requiere entender los distintos tipos de página, decidir una política de normalización (scheme/host/trailing slash) y manejar paginación y parámetros. Con los ejemplos provistos (simple y avanzado) tienes una base sólida para personalizar la canonical según las necesidades de tu proyecto y evitar problemas de contenido duplicado. Aplica las comprobaciones de plugins SEO, prueba en todas las plantillas y verifica en Search Console para asegurarte de que Google entiende la URL preferida.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |