Javascript 用于丰富代码段的JSON-LD模式和GatsbyJS

Javascript 用于丰富代码段的JSON-LD模式和GatsbyJS,javascript,reactjs,gatsby,google-rich-snippets,Javascript,Reactjs,Gatsby,Google Rich Snippets,我和盖茨比有一个基本的博客设置,在发布这个问题的时候。有一些基本的SEO组件的例子,但我想要的是更深入一点。也许,如果在这里达成了一个解决方案,它可以为《盖茨比文件》做出贡献,让其他人受益 除了通常的标题和描述元标记以及facebook/twitter开放图元(我已经做过了)之外,我还想添加结构化数据,这些数据根据博客文章类型的不同而有所不同。例如,我可能有一篇常规的文章会打印模式,有些文章可能是,在这种情况下,我想打印HowTo模式而不是文章。在某个时候,我可能会写一篇适合模式的文章 我不知道

我和盖茨比有一个基本的博客设置,在发布这个问题的时候。有一些基本的SEO组件的例子,但我想要的是更深入一点。也许,如果在这里达成了一个解决方案,它可以为《盖茨比文件》做出贡献,让其他人受益

除了通常的标题和描述元标记以及facebook/twitter开放图元(我已经做过了)之外,我还想添加结构化数据,这些数据根据博客文章类型的不同而有所不同。例如,我可能有一篇常规的文章会打印模式,有些文章可能是,在这种情况下,我想打印HowTo模式而不是文章。在某个时候,我可能会写一篇适合模式的文章

我不知道这是否是最好的方法,但我想:

1.在frontmatter中,将我想要的模式类型设置为true,其余的设置为false。 我也在考虑将模式数据存储在frontmatter中,但由于这些数据非常复杂,并且不同的帖子类型(文章、HowTo等)会有所不同,我不确定这是否是一个好主意

---
title: Hello World
description: How to say hello
article: false
how-to: true
faq: false
---
2.在SEO组件中测试真/假,并打印正确的模式。 下面是我的整个搜索引擎优化组件,这显然不起作用,但你有希望看到我的想法的方向。我已经解剖和借用了和,但都没有做我需要的。这是我的:

import React from "react"
import Helmet from "react-helmet"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"
import Facebook from "./Facebook"
import Twitter from "./Twitter"

const SEO = ({
  title,
  desc,
  banner,
  pathname,
  published,
  modified,
  article,
  webpage,
  node,
}) => {
  const { site } = useStaticQuery(query)

  const {
    buildTime,
    siteMetadata: {
      siteUrl,
      defaultTitle,
      defaultDescription,
      defaultBanner,
      headline,
      siteLanguage,
      ogLanguage,
      author,
      twitter,
      facebook,
    },
  } = site

  const seo = {
    title: title || defaultTitle,
    description: desc || defaultDescription,
    image: `${siteUrl}${banner || defaultBanner}`,
    url: `${siteUrl}${pathname || "/"}`,
    date_published: published,
    date_modified: modified,
  }

  // Default Website Schema
  const schemaOrgJSONLD = [
    {
      "@context": "http://schema.org",
      "@type": "WebSite",
      url: siteUrl,
      name: defaultTitle,
      alternateName: headline ? headline : "",
    },
  ]

  if (howto) {
    schemaOrgJSONLD.push({
      /* HowTo Schema here */
    })
  }
  
  if (faq) {
    schemaOrgJSONLD.push({
      /* FAQ Schema here */
    })
  }

  if (article) {
    schemaOrgJSONLD.push({
      /* Regular Article Schema */
      "@context": "http://schema.org",
      "@type": "Article",
      author: {
        "@type": "Person",
        name: author,
      },
      copyrightHolder: {
        "@type": "Person",
        name: author,
      },
      copyrightYear: "2019",
      creator: {
        "@type": "Person",
        name: author,
      },
      publisher: {
        "@type": "Organization",
        name: author,
        logo: {
          "@type": "ImageObject",
          url: `${siteUrl}${defaultBanner}`,
        },
      },
      datePublished: seo.date_published,
      dateModified: seo.date_modified,
      description: seo.description,
      headline: seo.title,
      inLanguage: siteLanguage,
      url: seo.url,
      name: seo.title,
      image: {
        "@type": "ImageObject",
        url: seo.image,
      },
      mainEntityOfPage: seo.url,
    })
  }

  return (
    <>
      <Helmet title={seo.title}>
        <html lang={siteLanguage} />
        <meta name="description" content={seo.description} />
        <meta name="image" content={seo.image} />
        {/* Schema.org tags */}
        <script type="application/ld+json">
          {JSON.stringify(schemaOrgJSONLD)}
        </script>
      </Helmet>
      <Facebook
        desc={seo.description}
        image={seo.image}
        title={seo.title}
        type={article ? "article" : "website"}
        url={seo.url}
        locale={ogLanguage}
        name={facebook}
      />
      <Twitter
        title={seo.title}
        image={seo.image}
        desc={seo.description}
        username={twitter}
      />
    </>
  )
}

export default SEO

SEO.propTypes = {
  title: PropTypes.string,
  desc: PropTypes.string,
  banner: PropTypes.string,
  pathname: PropTypes.string,
  published: PropTypes.string,
  modified: PropTypes.string,
  article: PropTypes.bool,
  webpage: PropTypes.bool,
  node: PropTypes.object,
}

SEO.defaultProps = {
  title: null,
  desc: null,
  banner: null,
  pathname: null,
  published: null,
  modified: null,
  article: false,
  webpage: false,
  node: null,
}

const query = graphql`
  query SEO {
    site {
      buildTime(formatString: "YYYY-MM-DD")
      siteMetadata {
        siteUrl
        defaultTitle: title
        defaultDescription: description
        defaultBanner: logo
        headline
        siteLanguage
        ogLanguage
        author
        logo
        twitter
        facebook
      }
    }
  }
`
从“React”导入React
从“反应头盔”导入头盔
从“道具类型”导入道具类型
从“盖茨比”导入{useStaticQuery,graphql}
从“/Facebook”导入Facebook
从“/Twitter”导入Twitter
常数SEO=({
标题
描述,
横幅,
路径名,
出版,
被改进的,
文章
网页,
节点,
}) => {
const{site}=useStaticQuery(查询)
常数{
建造时间,
站点元数据:{
siteUrl,
默认标题,
默认描述,
默认横幅,
大字标题
网站语言,
语言,
作者
啁啾
脸谱网,
},
}=站点
常数seo={
标题:标题| |默认标题,
description:desc | | defaultDescription,
图片:`${siteUrl}${banner | | defaultBanner}`,
url:`${siteUrl}${pathname | |“/”}`,
发布日期:发布日期:,
修改日期:已修改,
}
//默认网站架构
常量schemaOrgJSONLD=[
{
“@context”:”http://schema.org",
“@type”:“网站”,
url:siteUrl,
姓名:defaultTitle,
备选名称:标题?标题:“”,
},
]
如果(如何){
schemaOrgJSONLD.push({
/*如何在这里创建模式*/
})
}
如果(常见问题){
schemaOrgJSONLD.push({
/*常见问题解答模式*/
})
}
国际单项体育联合会(第条){
schemaOrgJSONLD.push({
/*常规文章模式*/
“@context”:”http://schema.org",
“@type”:“Article”,
作者:{
“@type”:“Person”,
姓名:作者,
},
版权持有人:{
“@type”:“Person”,
姓名:作者,
},
版权年份:“2019年”,
创建者:{
“@type”:“Person”,
姓名:作者,
},
出版商:{
“@type”:“组织”,
姓名:作者,
标志:{
“@type”:“ImageObject”,
url:`${siteUrl}${defaultBanner}`,
},
},
datePublished:seo.date_published,
dateModified:seo.date\u modified,
description:seo.description,
标题:seo.title,
inLanguage:siteLanguage,
url:seo.url,
名称:seo.title,
图片:{
“@type”:“ImageObject”,
网址:seo.image,
},
页面的维护:seo.url,
})
}
返回(
{/*Schema.org标记*/}
{JSON.stringify(schemaOrgJSONLD)}
)
}
导出默认搜索引擎优化
SEO.propTypes={
标题:PropTypes.string,
desc:PropTypes.string,
横幅:PropTypes.string,
路径名:PropTypes.string,
已发布:PropTypes.string,
修改:PropTypes.string,
文章:PropTypes.bool,
网页:PropTypes.bool,
节点:PropTypes.object,
}
SEO.defaultProps={
标题:空,
desc:null,
横幅:空,
路径名:null,
已发布:null,
修改:null,
第条:虚假,
网页:假,,
节点:null,
}
const query=graphql`
查询搜索引擎优化{
场地{
构建时间(格式字符串:“YYYY-MM-DD”)
站点元数据{
站点URL
默认标题:标题
defaultDescription:description
默认横幅:徽标
大字标题
站点语言
奥格语言
作者
标志
啁啾
脸谱网
}
}
}
`
我看到的问题是:
  • 如何测试要使用的架构类型并打印它
  • 包括所有类型的面包屑模式
  • 仅打印单个模式JSON-LD脚本标记,避免任何重复模式
  • 在标记文件中使用frontmatter是否适合存储复杂的模式数据
  • 检索架构的frontmatter数据
  • 我决定了这个解决办法。 在前面:

    ---
    type: howto // Use either 'article' or 'howto'
    ---
    
    使用GraphQL查询它,就像查询其他数据一样:

    frontmatter {
     title
     published(formatString: "MMMM DD, YYYY")
     modified(formatString: "MMMM DD, YYYY")
     description
     type
    }
    
    将其传递给您的SEO组件:

    
    
    在您的SEO组件中,您可以这样使用它(对所有类型都这样做)。您可以根据需要为我的类型、常见问题解答、课程等设置帖子和SEO组件:

    const schemaType=type
    if(schemaType==“howto”){
    方案={
    //这里是您的howto模式
    }
    }
    if(schemaType==“article”){
    schemaArticle={
    //您的文章架构在这里
    }
    }
    
    最后,我们有:

    
    {schemaType===“howto”&&(
    {JSON.stringify(schemaHowTo)}
    )}
    {schemaType===“article”&&(
    {JSON.stringify(schemaArticle)}
    )}
    ...
    
    您可以将schemaType作为schema对象的属性,然后根据schemaType动态引用它们。stringify(schemas[schemaType]),或者如果您想保持原样,可以更改为JSON.stringi