У меня есть базовая настройка блога с Gatsby, и на момент публикации этого вопроса не хватает хорошей документации для SEO-компонентов . Есть примеры основных компонентов SEO, но я хочу немного углубиться. Возможно, если решение будет достигнуто здесь, оно может быть внесено в документы Gatsby для других пользователей.
Помимо обычных метатегов заголовка и описания и мета открытого графика в Facebook / Twitter (что я и сделал)уже), я хочу добавить структурированные данные для богатых фрагментов , которые будут варьироваться в зависимости от типа сообщения в блоге. Например, у меня может быть обычное сообщение, которое будет печатать схему Article , некоторые сообщения могут быть How-to , в этом случае я хотел бы напечатать схему HowTo вместо Article. В какой-то момент я мог бы написать сообщение с подходящей схемой FAQ .
Я не знаю, является ли это лучшим подходом, но вот что я думаю:
1. Во frontmatter установите тип схемы, который я хочу установить в true, оставьте значение false.
Я также думаю о сохранении данных схемы во frontmatter, но так как эти данные довольно сложны и будут варьироваться от типа записи к типу записи(Статья, HowTo и т. Д.) Я не уверен, что это хорошая идея?
---
title: Hello World
description: How to say hello
article: false
how-to: true
faq: false
---
2. Проверьте истинность / ложь в компоненте SEO и распечатайте правильную схему.
Ниже приведен весь мой компонент 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
}
}
}
`
Проблемы, которые я вижу:
- Как проверить, какой тип схемы использовать и распечатать его
- Включить схему хлебных крошек длявсе типы
- Печать только одного тега сценария JSON-LD схемы, исключая любую дублирующуюся схему
- Использует frontmatter в файлах уценки, подходящих для хранения сложных данных схемы
- Получение данных frontmatterдля схемы