URL 结构

URL 结构是 SEO 策略的重要组成部分。虽然 Google 并未公开 SEO 各部分的权重占比,但无论 URL 结构最终对排名影响大小,遵循最佳实践构建优质的 URL 都被视为重要准则。

建议遵循以下原则:

  • 语义化:最好使用具有语义的 URL,即使用单词而非 ID 或随机数字。例如:/learn/basics/create-nextjs-app 优于 /learn/course-1/lesson-1
  • 逻辑一致的模式:URL 应遵循页面间一致的逻辑模式。例如,应将所有产品页面归入同一文件夹,而非为每个产品设置不同路径
  • 关键词聚焦:Google 的排名系统仍很大程度上基于网站包含的关键词。建议在 URL 中使用关键词以明确页面用途
  • 避免参数化:通常不建议使用参数构建 URL。多数情况下参数不具备语义,搜索引擎可能混淆其含义并降低排名

Next.js 中如何定义路由?

Next.js 采用基于 页面 (pages) 概念的 文件系统路由。当文件被添加至 pages 目录时,它会自动成为可用路由。pages 目录中的文件和文件夹可用于定义大多数常见路由模式。

以下是简单 URL 及其在 Next.js 路由中的实现方式:

  • 首页https://www.example.compages/index.js
  • 列表页https://www.example.com/productspages/products.jspages/products/index.js
  • 详情页https://www.example.com/products/productpages/products/product.js

对于博客或电商网站,通常需要使用产品 ID 或博客名称作为 URL 的 动态路由 参数:

  • 产品页https://www.example.com/products/nextjs-shirtpages/products/[product].js
  • 博客页https://www.example.com/blog/seo-in-nextjspages/blog/[blog-name].js

要实现动态路由,只需在 productsblogs 子文件夹中的页面文件名添加方括号。

以下是使用 SSG (静态生成) 优化的页面示例:

// pages/blog/[slug].js
 
import Head from 'next/head';
 
export async function getStaticPaths() {
  // 调用外部 API 获取文章列表
  const res = await fetch('https://www.example.com/api/posts');
  const posts = await res.json();
 
  // 根据文章生成预渲染路径
  const paths = posts.map((post) => ({
    params: { slug: post.slug },
  }));
  // 设置 fallback 为 blocking。构建后新增的文章将通过 SSR 确保 SEO
  // 后续请求将使用静态页面
  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;

以下是使用 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;

延伸阅读

On this page