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', {
'col--7': hasSidebar,
'col--9 col--offset-1': !hasSidebar,
})}>
})}
itemScope
itemType="http://schema.org/Blog">
{children}
</main>
{toc && (

View file

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

View file

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