如何在 Gatsby 中创建规范 URL?

发布: (2026年2月1日 GMT+8 16:30)
7 min read
原文: Dev.to

Source: Dev.to

关于在 Gatsby 中创建规范 URL 的封面图

Dejan Kostevski

介绍

在我之前的某篇文章中,我描述了什么是规范 URL。现在,让我向您展示如何在 Gatsby 中实现它。

Gatsby

Gatsby 是什么?
Gatsby 是一个基于 React 的开源框架,用于创建网站和应用。

  • 它是一个基于 React 的静态站点生成器(SSG)。
  • 它会将你的 React 组件预渲染为 HTML 文件。
  • 它提供了插件生态系统和活跃的社区。

在 Gatsby 将你的组件渲染成 HTML 页面后,你可以在任意托管平台上将其作为静态网站进行部署。

React Helmet

React Helmet 是什么?
React Helmet 是一个可复用的 React 组件,能够让你在 Gatsby 项目中管理所有的 <head> 标签。

import React from "react";
import { Helmet } from "react-helmet";

class Application extends React.Component {
  render() {
    return (
      <Helmet>
        <title>My Title</title>
        {/* other head tags */}
      </Helmet>
    );
  }
}

当 Gatsby 渲染 HTML 时,你将得到:

<head>
  <title>My Title</title>
  <!-- other head tags -->
</head>

安装

npm install gatsby-plugin-react-helmet react-helmet

gatsby-plugin-react-helmet-canonical-urls

React Helmet 工作良好,但它会与 gatsby-plugin-canonical-urls 冲突。两者同时使用可能导致出现 两个 canonical <link> 标签。

gatsby-plugin-react-helmet-canonical-urls 插件通过允许默认的 canonical 标签,并可以通过 React Helmet 覆盖,从而解决此问题。

安装

npm install --save gatsby-plugin-react-helmet gatsby-plugin-react-helmet-canonical-urls

配置 (gatsby-config.js)

// gatsby-config.js
module.exports = {
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-plugin-react-helmet-canonical-urls`,
      options: {
        siteUrl: "https://www.example.com",
      },
    },
  ],
};

查看完整的选项列表请参见此处:.

在静态页面上使用规范 URL

示例组件(about.jsx

import React from "react";
import { Helmet } from "react-helmet";
import Layout from "../components/layout";

export default ({ data, location }) => (
  <Layout>
    <Helmet>
      <title>{`${data.site.siteMetadata.title} - About`}</title>
      <link
        rel="canonical"
        href={`${data.site.siteMetadata.siteUrl}${location.pathname}`}
      />
    </Helmet>

    <h1>About me</h1>
    {/* page content */}
  </Layout>
);

站点元数据(gatsby-config.js

module.exports = {
  siteMetadata: {
    title: "Kode Skills",
    siteUrl: "https://kodeskills.com/",
  },
};

GraphQL 查询

export const query = graphql`
  {
    site {
      siteMetadata {
        title
        siteUrl
      }
    }
  }
`;

location 属性(参见 Gatsby 文档)会自动传递给页面组件,使你能够通过 siteUrllocation.pathname 构建完整的规范 URL。

结论

通过将 React Helmetgatsby-plugin-react-helmet-canonical-urls 结合使用,您可以:

  1. 为整个站点定义默认的规范 URL。
  2. 在需要时按页面覆盖该设置。
  3. 保持 <link rel="canonical"> 标签简洁且符合 SEO 要求。

祝构建愉快! 🚀

如何在 Gatsby 中创建规范 URL

什么是规范 URL?

规范 URL 告诉搜索引擎在存在多个 URL 拥有相同(或非常相似)内容时,哪个版本是“主”版本。它可以防止重复内容惩罚并合并链接权益。

在 Gatsby 中,你可以在每个页面的 <head> 中添加 <link rel="canonical"> 标签。其值应为页面的完整 URL(包括协议和域名)。

静态页面

对于静态页面,你可以使用站点的基础 URL(siteUrl)和页面的路径名(location.pathname)来构建规范 URL。

// src/pages/about.jsx
import React from "react";
import { graphql } from "gatsby";
import { Helmet } from "react-helmet";

export default ({ data, location }) => (
  <>
    <Helmet>
      <title>{data.site.siteMetadata.title} – About</title>
      <link
        rel="canonical"
        href={`${data.site.siteMetadata.siteUrl}${location.pathname}`}
      />
    </Helmet>

    {/* page content */}
  </>
);

export const query = graphql`
  {
    site {
      siteMetadata {
        title
        siteUrl
      }
    }
  }
`;
  • siteUrl 来自 gatsby-config.js
  • location.pathname 是域名之后的 URL 部分(例如 /about)。

动态模板

当你有一个模板会被多个内容(博客文章、标签页等)复用时,可以从 Markdown 的 front‑matter 中获取 slug,并以相同方式构建规范 URL。

1. 在 front‑matter 中添加 slug

---
slug: "how-to-create-canonical-urls-in-gatsby"
title: "How to create canonical URLs in Gatsby?"
---

2. 查询数据

# src/templates/blog-post.jsx
export const query = graphql`
  query BlogPostQuery($slug: String!) {
    site {
      siteMetadata {
        siteUrl
      }
    }
    markdownRemark(frontmatter: { slug: { eq: $slug } }) {
      frontmatter {
        slug
        title
      }
    }
  }
`;

3. 在组件中使用数据

// src/templates/blog-post.jsx
import React from "react";
import { Helmet } from "react-helmet";

export default ({ data }) => (
  <>
    <Helmet>
      <title>{data.markdownRemark.frontmatter.title}</title>
      <link
        rel="canonical"
        href={`${data.site.siteMetadata.siteUrl}/${data.markdownRemark.frontmatter.slug}`}
      />
    </Helmet>

    {/* the content of your blog post */}
  </>
);

可复用的 SEO 组件

为了避免在每个页面或模板中重复相同的 <Helmet> 逻辑,可以创建一个小的 Seo 组件,然后在任意页面或模板中使用它。

// src/components/Seo.jsx
import React from "react";
import { Helmet } from "react-helmet";

export const Seo = ({ canonicalUrl, siteTitle, title }) => (
  <Helmet>
    <title>{siteTitle} – {title}</title>
    {canonicalUrl && <link rel="canonical" href={canonicalUrl} />}
  </Helmet>
);

在静态页面中使用

// src/pages/about.jsx
import React from "react";
import { graphql } from "gatsby";
import { Seo } from "../components/Seo";

export default ({ data, location }) => (
  <>
    <Seo
      siteTitle={data.site.siteMetadata.title}
      title="About"
      canonicalUrl={`${data.site.siteMetadata.siteUrl}${location.pathname}`}
    />
    {/* page content */}
  </>
);

export const query = graphql`
  {
    site {
      siteMetadata {
        title
        siteUrl
      }
    }
  }
`;

在动态博客文章模板中使用

// src/templates/blog-post.jsx
import React from "react";
import { graphql } from "gatsby";
import { Seo } from "../components/Seo";

export default ({ data }) => (
  <>
    <Seo
      siteTitle={data.site.siteMetadata.title}
      title={data.markdownRemark.frontmatter.title}
      canonicalUrl={`${data.site.siteMetadata.siteUrl}/${data.markdownRemark.frontmatter.slug}`}
    />
    {/* post content */}
  </>
);

export const query = graphql`
  query BlogPostQuery($slug: String!) {
    site {
      siteMetadata {
        ... 
 title
        siteUrl
      }
    }
    markdownRemark(frontmatter: { slug: { eq: $slug } }) {
      frontmatter {
        slug
        title
      }
    }
  }
`;

结论

为任何网站设置规范 URL 是您应该采取的首要 SEO 步骤之一。当您将内容同步到其他平台(Medium、dev.to 等)时,这一点尤为重要。

使用 Gatsby,您可以为静态页面和动态模板自动生成规范 URL,且一个小型可复用的 Seo 组件可以保持代码 DRY 并易于维护。

Back to Blog

相关文章

阅读更多 »

ReactJS ~React Server Components~

ReactJS 的封面图片 ~React Server Components~ https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev...