refactor: add blog microdata in markup instead of use JSON-LD (#5355)

* refactor: add blog microdata in markup intead of use JSON-LD

* Add check for authorTitle
This commit is contained in:
Alexey Pyltsyn 2021-08-17 13:21:25 +03:00 committed by GitHub
parent 09a954165c
commit ee6882650e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 87 deletions

View file

@ -31,7 +31,9 @@ function BlogLayout(props: Props): JSX.Element {
className={clsx('col', { className={clsx('col', {
'col--7': hasSidebar, 'col--7': hasSidebar,
'col--9 col--offset-1': !hasSidebar, 'col--9 col--offset-1': !hasSidebar,
})}> })}
itemScope
itemType="http://schema.org/Blog">
{children} {children}
</main> </main>
{toc && ( {toc && (

View file

@ -10,6 +10,7 @@ import clsx from 'clsx';
import {MDXProvider} from '@mdx-js/react'; import {MDXProvider} from '@mdx-js/react';
import Translate, {translate} from '@docusaurus/Translate'; import Translate, {translate} from '@docusaurus/Translate';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import {usePluralForm} from '@docusaurus/theme-common'; import {usePluralForm} from '@docusaurus/theme-common';
import MDXComponents from '@theme/MDXComponents'; import MDXComponents from '@theme/MDXComponents';
import Seo from '@theme/Seo'; import Seo from '@theme/Seo';
@ -40,6 +41,7 @@ function useReadingTimePlural() {
function BlogPostItem(props: Props): JSX.Element { function BlogPostItem(props: Props): JSX.Element {
const readingTimePlural = useReadingTimePlural(); const readingTimePlural = useReadingTimePlural();
const {withBaseUrl} = useBaseUrlUtils();
const { const {
children, children,
frontMatter, frontMatter,
@ -74,11 +76,19 @@ function BlogPostItem(props: Props): JSX.Element {
return ( return (
<header> <header>
<TitleHeading className={styles.blogPostTitle}> <TitleHeading className={styles.blogPostTitle} itemProp="headline">
{isBlogPostPage ? title : <Link to={permalink}>{title}</Link>} {isBlogPostPage ? (
title
) : (
<Link itemProp="url" to={permalink}>
{title}
</Link>
)}
</TitleHeading> </TitleHeading>
<div className={clsx(styles.blogPostData, 'margin-vert--md')}> <div className={clsx(styles.blogPostData, 'margin-vert--md')}>
<time dateTime={date}>{formattedDate}</time> <time dateTime={date} itemProp="datePublished">
{formattedDate}
</time>
{readingTime && ( {readingTime && (
<> <>
@ -93,16 +103,25 @@ function BlogPostItem(props: Props): JSX.Element {
<img src={authorImageURL} alt={author} /> <img src={authorImageURL} alt={author} />
</Link> </Link>
)} )}
<div className="avatar__intro"> {author && (
{author && ( <div
<> className="avatar__intro"
<div className="avatar__name"> itemProp="author"
<Link href={authorURL}>{author}</Link> itemScope
</div> itemType="https://schema.org/Person">
<small className="avatar__subtitle">{authorTitle}</small> <div className="avatar__name">
</> <Link href={authorURL} itemProp="url">
)} <span itemProp="name">{author}</span>
</div> </Link>
</div>
{authorTitle && (
<small className="avatar__subtitle" itemProp="description">
{authorTitle}
</small>
)}
</div>
)}
</div> </div>
</header> </header>
); );
@ -112,11 +131,24 @@ function BlogPostItem(props: Props): JSX.Element {
<> <>
<Seo {...{keywords, image}} /> <Seo {...{keywords, image}} />
<article className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}> <article
className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}
itemProp="blogPost"
itemScope
itemType="http://schema.org/BlogPosting">
{renderPostHeader()} {renderPostHeader()}
<div className="markdown">
{image && (
<meta
itemProp="image"
content={withBaseUrl(image, {absolute: true})}
/>
)}
<div className="markdown" itemProp="articleBody">
<MDXProvider components={MDXComponents}>{children}</MDXProvider> <MDXProvider components={MDXComponents}>{children}</MDXProvider>
</div> </div>
{(tags.length > 0 || truncated) && ( {(tags.length > 0 || truncated) && (
<footer <footer
className={clsx('row docusaurus-mt-lg', { className={clsx('row docusaurus-mt-lg', {
@ -131,6 +163,7 @@ function BlogPostItem(props: Props): JSX.Element {
Tags: Tags:
</Translate> </Translate>
</b> </b>
{tags.map(({label, permalink: tagPermalink}) => ( {tags.map(({label, permalink: tagPermalink}) => (
<Link <Link
key={tagPermalink} key={tagPermalink}

View file

@ -8,7 +8,6 @@
import React from 'react'; import React from 'react';
import BlogLayout from '@theme/BlogLayout'; import BlogLayout from '@theme/BlogLayout';
import BlogPostItem from '@theme/BlogPostItem'; import BlogPostItem from '@theme/BlogPostItem';
import BlogPostStructuredData from '@theme/BlogPostStructuredData';
import BlogPostPaginator from '@theme/BlogPostPaginator'; import BlogPostPaginator from '@theme/BlogPostPaginator';
import type {Props} from '@theme/BlogPostPage'; import type {Props} from '@theme/BlogPostPage';
import {ThemeClassNames} from '@docusaurus/theme-common'; import {ThemeClassNames} from '@docusaurus/theme-common';
@ -31,11 +30,6 @@ function BlogPostPage(props: Props): JSX.Element {
? BlogPostContents.toc ? BlogPostContents.toc
: undefined : undefined
}> }>
<BlogPostStructuredData
frontMatter={frontMatter}
frontMatterAssets={frontMatterAssets}
metadata={metadata}
/>
<BlogPostItem <BlogPostItem
frontMatter={frontMatter} frontMatter={frontMatter}
frontMatterAssets={frontMatterAssets} frontMatterAssets={frontMatterAssets}

View file

@ -1,47 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import Head from '@docusaurus/Head';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import type {Props} from '@theme/BlogPostStructuredData';
function BlogPostStructuredData(props: Props): JSX.Element {
const {withBaseUrl} = useBaseUrlUtils();
const {frontMatter, frontMatterAssets, metadata} = props;
const {date, title, description} = metadata;
const image = frontMatterAssets.image ?? frontMatter.image;
const {author} = frontMatter;
const authorURL = frontMatter.author_url || frontMatter.authorURL;
// details on structured data support: https://developers.google.com/search/docs/data-types/article#non-amp
// and https://schema.org/BlogPosting
const blogPostStructuredData = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: title,
description,
...(image ? {image: [withBaseUrl(image, {absolute: true})]} : {}),
datePublished: date,
author: {
'@type': 'Person',
...(author ? {name: author} : {}),
url: authorURL,
},
};
return (
<Head>
<script type="application/ld+json">
{JSON.stringify(blogPostStructuredData)}
</script>
</Head>
);
}
export default BlogPostStructuredData;

View file

@ -46,24 +46,6 @@ declare module '@theme/BlogPostItem' {
export default BlogPostItem; export default BlogPostItem;
} }
declare module '@theme/BlogPostStructuredData' {
import type {
FrontMatter,
FrontMatterAssets,
Metadata,
} from '@theme/BlogPostPage';
export type Props = {
readonly frontMatter: FrontMatter;
readonly frontMatterAssets: FrontMatterAssets;
readonly metadata: Metadata;
readonly truncated?: string | boolean;
};
const BlogPostStructuredData: (props: Props) => JSX.Element;
export default BlogPostStructuredData;
}
declare module '@theme/BlogPostPaginator' { declare module '@theme/BlogPostPaginator' {
type Item = {readonly title: string; readonly permalink: string}; type Item = {readonly title: string; readonly permalink: string};