gatsby - 使用 Markdown 在 Gatsby 布局组件中动态添加页面元

我的目标:向 Layout 组件添加代码,以便根据 frontmatter 中提供的内容使用用户所在的当前页面更新 Meta 标题、描述和图像。例如,如果用户导航到 about 页面,则元数据应显示以下内容:

<title>About | Website</title>
<meta content="This is the about page" name="description">
<link rel="canonical" href="www.website.com/about" />
<meta property="og:image" content="/images/about-meta.png" />

在关于页面上,相应的元是这样的:

---
title: About
description: This is the about page
meta_image: /images/about-meta.png
slug: about
---

我现在在做什么:我将 Helmet 标记中的所有信息添加到各个模板中,并且我在布局中设置了标题模板,但似乎必须有更好的方法来自动设置 Helmet布局中的组件来读取它。

布局.jsx

<Helmet
  defaultTitle={siteMetadata.title}
  titleTemplate={`%s | ${siteMetadata.title}`}
/>

模板/about.jsx

<Helmet title={frontmatter.title} >
  <meta property="og:image" content={frontmatter.meta_image}/>
  <link rel="canonical" href="{siteMetadata.siteUrl}/{frontmatter.slug}" />
</Helmet>

Gatsby 有这个关于创建 https://www.gatsbyjs.com/docs/add-seo-component/ 的指南,但它不包括如何从页面模板中工作并使用行话来定义行话,所以它对我来说并不是特别有用的反应小白。我不太了解 PropTypes 是什么或它们做什么。

我正在尝试什么:我想在布局中添加一个静态查询,该查询将检测当前页面 slug,然后根据当前 slug 获取 markdownremark 并动态填写元数据,因此我不必添加每个页面模板的头盔标签。

回答1

我正在尝试什么:我想在布局中添加一个静态查询,该查询将检测当前页面 slug,然后根据当前 slug 获取 markdownremark 并动态填写元数据,所以我没有为每个页面模板添加一个头盔标签。

这种方法是有效的,但是当您尝试避免在每个页面模板中添加 SEO 组件时,您正在更改组件的职责。在我看来,是在 SEO 组件中,您必须将 useStaticQuery(或 StaticQuery)放置在每个页面更改中将触发的内容,而不是在 Layout 中,它的唯一职责是显示共享布局该网站,不查询。此外,您可能会在孤立的页面(关于等)中进行页面查询,因此您已经在获取数据,因此没有必要不添加一些额外的行来添加 SEO。

此外,您将无法在 Layout 中添加查询,因为您只有两个选项:

实际上,它在您确切知道页面本身的元数据是什么的页面上,因此在您希望拥有所有 SEO 元数据的每个特定页面上使用 SEO 组件更容易和最干净。

如果您在 Layout 中查询内容,您将不必要地提升 props,因为它们总是会被获取、更改和向下钻取。

创建一个 SEO 组件,例如:

const SEO = ({ description, lang= "en-US", meta, title }) => {
  const { site } = useStaticQuery(graphql`
              query getAllMetadata {
                  site {
                      siteMetadata {
                          title
                          description
                          author
                      }
                  }
              }
    `,
  );
  const metaDescription = description ?? site.siteMetadata.description;

  return <Helmet htmlAttributes={{ lang }} title={title} titleTemplate={`%s | ${site.siteMetadata.title}`}>
    <meta name={`robots`} content={`index, follow`}/>
    <meta name={`description`} content={metaDescription}/>
    <meta name={`og:title`} content={title}/>
    <meta name={`og:description`} content={metaDescription}/>
    <meta name={`og:type`} content={`website`}/>
    <meta name={`twitter:card`} content={`summary`}/>
    <meta name={`twitter:creator`} content={site.siteMetadata.author}/>
    <meta name={`twitter:title`} content={title}/>
    <meta name={`twitter:description`} content={metaDescription}/>
  </Helmet>;
};

export default SEO;

您将查询特定于组件中的共享元数据(在本例中为 titledescriptionauthor,在 gatsby-config.jssiteMetadata 对象中添加),同时,它的组件仍然为放置它的每个特定页面的每个特定字段接收所需的数据(如 props)。

相似文章

最新文章