Estructura de URLs

La estructura de URLs es una parte importante de una estrategia de SEO. Aunque Google no revela qué peso tiene cada componente del SEO, se considera una buena práctica tener URLs bien estructuradas, independientemente de si terminan siendo un factor de ranking grande o pequeño.

Puede seguir estos principios:

  • Semántica: Es mejor usar URLs semánticas, es decir, que utilicen palabras en lugar de IDs o números aleatorios. Ejemplo: /learn/basics/create-nextjs-app es mejor que /learn/course-1/lesson-1
  • Patrones lógicos y consistentes: Las URLs deben seguir un patrón coherente entre páginas. Por ejemplo, conviene tener una carpeta que agrupe todas las páginas de productos, en lugar de tener rutas diferentes para cada producto.
  • Enfocadas en palabras clave: Google aún basa una parte considerable de sus sistemas en las palabras clave que contiene un sitio web. Puede usar palabras clave en sus URLs para facilitar la comprensión del propósito de las páginas.
  • No basadas en parámetros: Usar parámetros para construir URLs generalmente no es una buena idea. En la mayoría de los casos no son semánticos y los motores de búsqueda podrían confundirlos y reducir su posicionamiento en los resultados.

¿Cómo se definen las rutas en Next.js?

Next.js utiliza un sistema de enrutamiento basado en archivos construido sobre el concepto de páginas. Cuando se agrega un archivo al directorio pages, automáticamente está disponible como una ruta. Los archivos y carpetas dentro del directorio pages pueden usarse para definir los patrones más comunes.

Veamos algunos ejemplos de URLs simples y cómo agregarlas al enrutador de Next.js:

  • Página principal: https://www.example.compages/index.js
  • Listados: https://www.example.com/productspages/products.js o pages/products/index.js
  • Detalle: https://www.example.com/products/productpages/products/product.js

Para un blog o sitio de comercio electrónico, probablemente querrá usar el ID del producto o el nombre del blog como slug para la URL. Esto se llama enrutamiento dinámico:

  • Producto: https://www.example.com/products/nextjs-shirtpages/products/[product].js
  • Blog: https://www.example.com/blog/seo-in-nextjspages/blog/[blog-name].js

Para usar enrutamiento dinámico, puede agregar corchetes al nombre de una página dentro de su subcarpeta products o blogs.

Aquí un ejemplo de página optimizada para esto usando Generación de Sitios Estáticos (SSG):

// pages/blog/[slug].js
 
import Head from 'next/head';
 
export async function getStaticPaths() {
  // Llamar a un endpoint API externo para obtener posts
  const res = await fetch('https://www.example.com/api/posts');
  const posts = await res.json();
 
  // Obtener las rutas que queremos pre-renderizar basadas en los posts
  const paths = posts.map((post) => ({
    params: { slug: post.slug },
  }));
  // Establecer fallback como 'blocking'. Ahora cualquier nuevo post añadido después del build usará SSR
  // para garantizar SEO. Luego será estático para solicitudes posteriores
  return { paths, fallback: 'blocking' };
}
 
export async function getStaticProps({ params }) {
  const res = await fetch(`https://www.example.com/api/blog/${params.slug}`);
  const data = await res.json();
 
  return {
    props: {
      blog: data,
    },
  };
}
 
function BlogPost({ blog }) {
  return (
    <>
      <Head>
        <title>{blog.title} | My Site</title>
      </Head>
      <div>
        <h1>{blog.title}</h1>
        <p>{blog.text}</p>
      </div>
    </>
  );
}
 
export default BlogPost;

Aquí otro ejemplo usando Renderizado del Lado del Servidor (SSR):

// pages/blog/[slug].js
 
import Head from 'next/head';
function BlogPost({ blog }) {
  return (
    <div>
      <Head>
        <title>{blog.title} | My Site</title>
      </Head>
      <div>
        <h1>{blog.title}</h1>
        <p>{blog.text}</p>
      </div>
    </div>
  );
}
 
export async function getServerSideProps({ query }) {
  const res = await fetch(`https://www.example.com/api/blog/${query.slug}`);
  const data = await res.json();
 
  return {
    props: {
      blog: data,
    },
  };
}
 
export default BlogPost;

Lecturas adicionales

On this page