Gatsby: ¿barra final o no?

Como la mayoría de desarrolladores web junior, yo tenía poca o ninguna idea de qué era una barra final. Por supuesto, la usaba en los proyectos, pero más por sentido común (o incluso por intuición) que porque entendiera realmente el concepto.
La barra final es como la coma de Oxford: si no te has puesto a investigar el tema a propósito, lo más probable es que la pongas aquí y allá dejándote llevar por la intuición.
La barra final es el carácter de barra inclinada que se coloca al final de una URL. La convención general (respaldada por los estándares web) dice que, si una URL termina en barra, apunta a un directorio; si no, apunta a un archivo.
| Nombre de archivo | Archivo resultante | URL renderizada |
|---|---|---|
| blog.html | blog.html | mysite.io/blog |
| blog.js | blog/index.html | mysite.io/blog/ |
| index.js | /index.html | mysite.io/ |
Sé coherente con el uso de la barra final en tus proyectos y con tu equipo, porque la mayoría de las veces te tocará decidir a ti cuándo y cómo usarla.
¿De verdad tengo que tenerla en cuenta?
¡Sí! Puede dar problemas de SEO y de optimización del rendimiento.
Primero, no te interesa que un usuario esté navegando por /thisUrl y el host lo redirija a /thisUrl/ sin ninguna explicación.
Segundo, si en la misma web conviven dos URL, una con barra final y otra sin ella, es difícil enlazarlas correctamente y, además, se reduce la autoridad de enlaces que Google asigna a tu web.
Aquí tienes un ejemplo de mal uso de la barra final: dos páginas, una con barra y otra sin ella, conviven sin redirección entre ellas y sin explicación alguna:
Otro ejemplo: en el vídeo de abajo se ve una mala experiencia de usuario, en la que el host añade la barra final y luego el router de front-end de una SPA la quita, de modo que el usuario ve una URL que cambia y se queda bastante confundido.
Así que, para que un rastreador web te entienda bien, tienes que dejar claras tus intenciones con URL canónicas o con redirecciones. A partir de ahí, puedes tener tantas páginas idénticas como quieras.
¿Cómo funcionan las barras finales al generar el sitio en Gatsby? ¿Qué pasa dentro de la función createPage()?
Este es un ejemplo típico del árbol de archivos de un proyecto Gatsby con la carpeta de páginas templates:
├── src│ ├── templates│ │ ├── 404.jsx│ │ ├── blog.jsx│ │ ├── demo.jsx│ │ ├── index.jsx│ │ └── product.jsx│ └── html.jsx├── gatsby-browser.js├── gatsby-config.js└── gatsby-node.js
Y esta es la carpeta public correspondiente, con todas las páginas creadas:
├── public│ ├── blog│ │ ├── index.html│ ├── demo│ │ ├── index.html│ ├── product│ │ ├── index.html├── 404.html└── index.html
Veamos cómo funciona este proceso de creación de páginas y qué necesitas saber sobre las barras finales para entender bien la mecánica.
La función createPage() recibe y procesa el argumento path. Puede ocurrir de forma «automática», cuando la página se genera a partir de un archivo .js de la carpeta src/pages/*, o de forma programática, cuando la ruta deseada se pasa explícitamente en la llamada a createPage() dentro de gatsby-node.js. En cualquier caso, la cadena path de createPage() le indica a Gatsby el lugar exacto donde construir el HTML.
createPage({ path: `/my-path/`, component: path.resolve(`./src/templates/my-path.js`),});
Por ejemplo, si tu carpeta src/pages/* contiene un archivo llamado product.js, /product es la ruta donde se construirá el HTML. Y aquí está el motivo por el que deberías usar barras finales en Gatsby: la cadena path que se pasa a createPage() se convierte en un directorio, y el HTML resultante queda en /product/index.html. Lo mismo ocurre con cualquier path que pases, termine o no en barra.
Podríamos decir que Gatsby genera carpetas, no archivos, con solo tres excepciones: las rutas que terminan explícitamente en .html pasadas a createPage() en gatsby-node.js, la página 404, que se genera en public/404.html, y el índice del sitio.
createPage({ path: `/404/`, component: path.resolve(`./src/templates/404.js`),}); // the 404 page is going to be created at public/404.html
¿Qué diferencia hay entre blog.html y blog/index.html en el lado del cliente?
No es un caso muy habitual, porque en proyectos reales casi nadie usa rutas como blog.html, pero creo que es fundamental tener una visión completa de todas las opciones posibles.
Como hemos visto, la generación de páginas da resultados distintos según la ruta que pases a createPage() termine en .html o no. Y eso también provoca diferencias en el lado del cliente. path='/blog.html' genera blog.html, y esa página está disponible en mysite.io/blog.
En cambio, path='/blog' o path='/blog/' generan el HTML en /blog/index.html, y esa página debería estar disponible en mysite.io/blog/. Si no se hace bien, esto puede confundir al usuario y causar problemas de SEO por contenido duplicado, así que, de nuevo, lo mejor es ser coherente al generar las páginas.
No olvides que, como /blog y /blog/ generan el mismo /blog/index.html, desde el punto de vista de los estándares web deberías usar siempre la barra final (es decir, '/blog/') al crear páginas de forma programática o al añadir enlaces fijos en la página.
createPage({ path: `/blog`, component: path.resolve(`./src/templates/blog.js`),});
createPage({ path: `/blog.html`, component: path.resolve(`./src/templates/blog.js`),});
Configuración de la barra final en Gatsby: ¿cómo está ahora y qué nos traerá el futuro?
Por ahora no hay una estandarización explícita, y verás que Gatsby no impone el uso de barras finales en tus proyectos ni en la v3 ni en la v4. En versiones anteriores a la 4.7, la solución era usar plugins (gatsby-plugin-force-trailing-slashes o gatsby-plugin-remove-trailing-slashes).
Sin embargo, desde Gatsby 4.7 existe la opción trailingSlash, que puedes definir en el gatsby-config.js de tu proyecto en lugar de usar un plugin adicional. Tiene tres valores:
always: añade siempre la barra final a cada URL, por ejemplo, de/xa/x/.never: elimina todas las barras finales de cada URL, por ejemplo, de/x/a/x.ignore: no modifica la URL automáticamente.
module.exports = { trailingSlash: `always`,};
En Gatsby v3/v4, el valor por defecto es legacy, para no romper nada en los proyectos existentes.
En Gatsby v5, el valor por defecto de esta opción será always, lo que significa que Gatsby apostará por el uso explícito de la barra final.
La tabla siguiente muestra cómo gestiona Gatsby Cloud (y también el propio Gatsby con gatsby develop y gatsby serve) las redirecciones según el valor de trailingSlash:
La página de ejemplo está en https://example.io/blog/index.html.
Valor de trailingSlash | URL solicitada | Código de redirección | URL renderizada |
|---|---|---|---|
| ignore | /blog | ninguno | /blog |
| ignore | /blog/ | ninguno | /blog/ |
| ignore | /blog/index.html | ninguno | blog/ |
| always | /blog | 301 | /blog/ |
| always | /blog/ | ninguno | /blog/ |
| always | /blog/index.html | ninguno | /blog/ |
| never | /blog | ninguno | /blog |
| never | /blog/ | 301 | /blog |
| never | /blog/index.html | ninguno | /blog |
Ten en cuenta que esta opción de configuración solo afecta al comportamiento en el lado del cliente; el comportamiento real en el servidor sigue dependiendo del proveedor de hosting o de la configuración de tu servidor web.
Extra: ¿cómo gestionan las distintas plataformas las redirecciones con y sin barra final?
Hay una página estupenda de @slorber que resume el despliegue de un sitio estático básico en distintas plataformas de hosting.
Su completa tabla muestra cómo gestionan las redirecciones distintas plataformas (Vercel, Cloudflare Pages, GitHub Pages, Netlify) para este sencillo sitio estático:
static│├── file.html│├── folder│ └── index.html│├── both.html└── both└── index.html
La idea principal es que la confusión y la imprevisibilidad surgen porque no existe una convención común entre proveedores de hosting y generadores de sitios estáticos sobre cómo tratar las barras finales de forma estandarizada. Así que la solución a todos estos posibles problemas es ser coherente con las barras finales, por ejemplo, usando Gatsby 4.7 o superior con la configuración trailingSlash: 'always'.
Resumen
Entender la barra final es fundamental para cualquier desarrollador web, pero solemos prestarle atención solo cuando algo falla en el SEO o en las redirecciones de la web. Espero que este artículo te haya aclarado lo básico sobre cómo trabajar con barras finales y URL, y que te ayude a tomar mejores decisiones en tu d ía a día como desarrollador.
Enlaces útiles
Guía de la barra final: proveedores de hosting