URL Mayúsculas y minúsculas
Gestionar las mayúsculas en una URL

- Autor:
-
Carlos Sánchez
- Temática:
- Rastreo ,
- Servidores
- Fecha de publicación:
- 2023-04-18
- Última revisión:
- 2023-11-07
Una URL se puede diferenciar de otra simplemente por las mayúsculas. A esto se le conoce como Case Sensitive. Y por defecto, aunque sean URLs distintas, ciertas tecnologías como podría ser el CMS de WordPress, genera el mismo contenido.
Esto genera una duplicidad de página como si fuera una versión distinta, y a veces tiene su self-canonical y un código de respuesta 200. Es decir, puede dar lugar a una canibalización e incluso ser un coladero para ataques de SEO negativo.
Es decir, si se tiene la URL:
https://example.com/contenido/
Es una URL distinta de:
https://example.com/Contenido/
Dependiendo del CMS o Framework, es posible que ambas ofrezcan exactamente el mismo contenido.
Con suerte, puede ser que la canonical apunte hacia la versión en minúsculas. Pero dependiendo de qué se use para la canonical, no siempre se consigue.
Para evitar estos problemas, se puede recurrir a la canonical, y muchas extensiones/plugins de SEO lo hacen así.
Las 3 opciones más aceptadas para esta práctica serían:
- Generar un código de respuesta 404 ya que estas URLs no existen y no tiene sentido el duplicado.
- Generar un canonical hacia la versión sin mayúsculas y así evitar la canibalización.
- Generar una redirección hacia la versión sin mayúsculas, de esta forma se evita el contenido duplicado, y puede ayudar de cara al User-Experience.
Redireccionar de Mayúsculas a minúsculas
Este es un cambio que se debe hacer desde el Servidor. Como hay lenguajes de programación que te pueden permitir mayor maniobrabilidad, yo para esto hago una combinación entre el servidor y el lenguaje que se emplea. En este caso, combino Apache con PHP.
.htaccess
<IfModule mod_rewrite.c>
#Redireccionar de mayusculas a minusculas
RewriteEngine On
RewriteBase /
# Busco cualquier rastro de mayúsculas en la URL
RewriteCond %{REQUEST_URI} [A-Z]
# Evito redireccionar contenido multimedia que pueda ocasionar redirecciones a un archivo de imágenes
RewriteCond %{REQUEST_URI} !\.(css|js|woff|woff2|svg|jpg|jpeg|webp|avif|mp4|pdf|png|gif|bmp)$ [NC]
# Llamo a un archivo .php que ponga en el root o la misma carpeta del .htaccess donde pondremos el código de después
RewriteRule ^(.*)$ lowercase.php?q=$1 [L,QSA]
</IfModule>
nginx
location / {
if ($request_uri ~* "[A-Z]") {
rewrite ^(.*)$ /lowercase.php?q=$1 last;
}
if ($request_uri ~* "\.(css|js|woff|woff2|svg|jpg|jpeg|webp|avif|mp4|pdf|png|gif|bmp)$") {
break;
}
}
Archivo de PHP
Tiene que tener el mismo nombre que el archivo al que se ha llamado, pues sería este.
<?php
// Redireccionar la versión de mayúsculas a la versión de minúsculas. A esto se le llama desde el .htaccess
if(isset($_GET['q'])) {
$url = strtolower($_GET['q']);
$request_uri = $_SERVER['REQUEST_URI'];
// En este caso vamos a hacer un condicional, para que siempre tenga barra al final, y no se duplique dicha barra. En caso contrario habría que hacerlo al revés, si tiene barra eliminarla
if($url !== $_GET['q'] || substr($request_uri, -1) !== '/') {
if(substr($request_uri, -1) === '/') {
$new_url = str_replace($_GET['q'], $url, $request_uri);
} else {
$new_url = str_replace($_GET['q'], $url, $request_uri) . '/';
}
header("HTTP/1.1 301 Moved Permanently");
header("Location: ".$new_url);
exit();
}
}
?>
Extra: Hashbangs
Los fragmentos de URL no se pueden redireccionar desde el servidor, ya que es una interacción entre el navegador y el usuario.
La única forma de redireccionar estas URL entonces es por medio de JavaScript, aunque no es mucho problema, ya que salvo contadas excepciones Google no rastrea los parámetros. Por lo tanto es una implementación que se haría simplemente para mejorar la experiencia del usuario.
Pero si se puede hacer por medio de JavaScript. Aquí expongo un ejemplo de como hacerlo para que redirecciones todos los fragmentos a su versión en minúscula, y que en el caso de tener "_" sea "-". Este código además es funcional en cuanto a que sigue aplicando el mismo desplazamiento que habría en caso de haberse aplicado de forma correcta.
document.addEventListener('DOMContentLoaded', function() {
var fragment = decodeURI(window.location.hash.substr(1));
if (fragment.indexOf('_') !== -1) {
var newFragment = fragment.replaceAll('_', '-').toLowerCase();
history.replaceState(null, '', window.location.href.replace(fragment, newFragment));
} else if (fragment.match(/[A-Z]/)) {
var newFragment = fragment.toLowerCase();
history.replaceState(null, '', window.location.href.replace(fragment, newFragment));
}
// Si hay un fragmento de URL, buscar el elemento correspondiente y desplazarse a él
if (fragment) {
var targetElement = document.getElementById(fragment);
if (targetElement) {
setTimeout(function() {
targetElement.scrollIntoView();
}, 100); // Espera 100ms antes de desplazarte
}
}
});
Explicación del código.
Para que este código funcione de una forma correcta, debe hacer el efecto de desplazamiento hacia el ID correspondiente. Normalmente el navegador realiza esta acción de forma automática. Pero si hacemos este tipo de redirecciones, tenemos que proveer de una pequeña ayuda.
Para lograr que el navegador se desplace a la sección correspondiente, debes utilizar la propiedad scrollIntoView() en el elemento que tenga el ID correspondiente al fragmento de la URL.
En este código, después de cambiar los guiones bajos y las mayúsculas, se verifica si hay un fragmento de URL. Si es así, se busca el elemento correspondiente en el DOM utilizando document.getElementById(), y si se encuentra, se desplaza hacia él utilizando scrollIntoView(). Esto hará que la página se desplace a la sección correcta de la página cuando se carga con un fragmento de URL en la barra de direcciones.
En este caso, para forzar el desplazamiento, conviene aplicar un breve retraso antes de llamar a scrollIntoView() para permitir que el navegador termine de renderizar la página.
Explicación del código de Apache
- <IfModule mod_rewrite.c>: Inicia una sección condicional que verifica si el módulo mod_rewrite está habilitado en el servidor Apache. Esto asegura que el bloque de reglas se ejecute solo si el módulo está activo.
- RewriteEngine On: Activa el motor de reescritura, que permite el procesamiento de reglas de reescritura en el archivo .htaccess.
- RewriteBase /: Establece la base para las reglas de reescritura. En este caso, se establece en la raíz del sitio web.
- RewriteCond %{REQUEST_URI} [A-Z]: Esta condición verifica si la URL contiene al menos una letra mayúscula en la parte de la ruta.
- RewriteCond %{REQUEST_URI} !\.(css|js|woff|woff2|svg|jpg|jpeg|webp|avif|mp4|pdf|png|gif|bmp)$ [NC]: Esta condición excluye la redirección para las URL que terminan en extensiones de archivos específicas (contenido multimedia), evitando así la redirección innecesaria de esos recursos. El modificador [NC] hace que la comparación no distinga entre mayúsculas y minúsculas.
- RewriteRule ^(.*)$ lowercase.php?q=$1 [L,QSA]: Esta regla es la que realiza la redirección. Toma la URL solicitada y la redirige a lowercase.php, pasando el valor de la URL original como parámetro q. El modificador [L] indica que esta es la última regla que se ejecutará, y [QSA] añade las variables de cadena de consulta existentes a la nueva URL.
- </IfModule>: Cierra la sección condicional del módulo mod_rewrite.
Explicación del código de nginx
- location /: Define cómo se manejará la ubicación raíz.
- if ($request_uri ~* "[A-Z]"): Esto verifica si la solicitud contiene letras mayúsculas en la URL.
- rewrite ^(.*)$ /lowercase.php?q=$1 last;: Si la solicitud contiene letras mayúsculas, esta línea de reescritura redirige la solicitud a lowercase.php, pasando el valor de la URL original como parámetro q. El modificador last indica que esta es la última instrucción en esta ubicación que se ejecutará.
- if ($request_uri ~* "\.(css|js|woff|woff2|svg|jpg|jpeg|webp|avif|mp4|pdf|png|gif|bmp)$"): Esta línea verifica si la solicitud termina con una de las extensiones de archivo multimedia listadas. Si es así, la solicitud se detiene y no se aplica la reescritura.
Ten en cuenta que el uso excesivo de instrucciones if en Nginx no es recomendado debido a su impacto en el rendimiento.
Bibliografía
Te falta mi máster. Accede a una formación avanzada que te permitirá aplicar e implementar SEO en cualquier tipo de WEB
¡Accede al Máster de SEO Técnico!