mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-04 01:09:20 +02:00
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:
parent
09a954165c
commit
ee6882650e
5 changed files with 51 additions and 87 deletions
|
@ -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 && (
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
18
packages/docusaurus-theme-classic/src/types.d.ts
vendored
18
packages/docusaurus-theme-classic/src/types.d.ts
vendored
|
@ -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};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue