-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(theme): use JSON-LD instead of microdata for blog structured data #9669
Conversation
…o json-ld-blog
✅ [V2]Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ [V2]
To edit notification comments on pull requests, go to your Netlify site configuration. |
⚡️ Lighthouse report for the deploy preview of this PR
|
Hi @Josh-Cena and @slorber! I was wondering if there were any thoughts about this PR? There's been no comments on it and so I'm not sure if you're aware it is here? I've been checking back every week or so for a while but there appears to be no activity. It's possible you're not interested in the PR - if so would you be able to let me know and I'll close it for tidiness sake? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry! I'm indeed aware of this. However my repo access isn't renewed so there isn't much I can do. If you've tested it yourself and it works, I'm personally happy to try it out and improve it where necessary.
packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
…turedData/index.tsx Co-authored-by: Joshua Chen <[email protected]>
…turedData/index.tsx Co-authored-by: Joshua Chen <[email protected]>
Yeah this PR was a Christmas project for me - I think it's a really good piece of work actually! (Of course I'm biased 😀) I think it puts the structured data story of Docusaurus in a really great place as it offers a really good default JSON-LD structured data story and freedom for users to straightforwardly control the structured data produced through the magic of swizzling. (In fact if they wanted to they could easily use the same mechanism to stop producing structured data)
I have indeed and I'm happy to take feedback to improve it as necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that seems reasonable to use the solution recommended by Google 👍
Review:
- I'd like to get rid of the 2 meta attributes you added
- We can probably reduce code duplication
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
Thanks for the review @slorber - useful points, will address them soon! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some additional changes requested and a few questions
If we merge this, should this be considered as a breaking change? 🤷♂️
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogListPage/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/StructuredData/index.tsx
Outdated
Show resolved
Hide resolved
// We're using dangerouslySetInnerHTML because we want to avoid React | ||
// transforming quotes into " which upsets parsers. | ||
// The entire contents is a stringified JSON object so it is safe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain how to reproduce that problem here?
Was the code we documented before affected by any issue?
<script type="application/ld+json">
{JSON.stringify({
'@context': 'https://schema.org/',
'@type': 'Organization',
name: 'Meta Open Source',
url: 'https://opensource.fb.com/',
logo: 'https://opensource.fb.com/img/logos/Meta-Open-Source.svg',
})}
</script>
Can you show side-by-side examples in a repro, before/after, rendering differently in practice? And explain how it upsets parsers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the code we documented before affected by any issue?
Yes.
So this was a curious one. The issue surfaces in the Google Search Console, and relates to the unsuccessful parsing of the inner JSON when it is directly rendered internally to the <script type="application/ld+json">
element. The Google Search Console sends a notification asking you to fix this issue:
Parsing error: Missing '}' or object member name.
This happens because by not using the dangerouslySetInnerHTML
approach, the "
characters in the JSON-LD are rendered as "
- which is not valid JSON. So something like this:
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Organization",
"name": "Meta Open Source",
"url": "https://opensource.fb.com/",
"logo": "https://opensource.fb.com/img/logos/Meta-Open-Source.svg"
}
</script>
Rather than:
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Organization",
"name": "Meta Open Source",
"url": "https://opensource.fb.com/",
"logo": "https://opensource.fb.com/img/logos/Meta-Open-Source.svg"
}
</script>
Curiously, Google will sometimes parse the "
style successfully. But more often it won't (TBH I'm surprised it ever succeeds). When I migrated to the dangerouslySetInnerHTML
approach instead it always parsed successfully and this fixed the issue being logged in the Google Search Console:
For reference, this is when I implemented the fix on my own site: https://github.com/johnnyreilly/blog.johnnyreilly.com/pull/664/files#diff-c2bd2d1e0092d85d7acaff15ce9223d0202ef706c2497f7500b1a24db9bc0366
No - I can't think of any reason why it would be
Cool - I've addressed these. See my responses above! |
Pre-flight checklist
Motivation
I originally contributed Structured Data support for blog posts back in 2021: #5322
@lex111 subsequently submitted a PR to migrate the approach to use microdata instead: #5355
I had reservations which I voiced at the time, but left it at that. Since then time I've had something of a baptism of fire around the world of SEO. And consequently I've been working with some excellent folk in the SEO industry to improve my own ranking. A thing that comes up repeatedly is a suggestion to use JSON-LD instead of microdata as that is what Google prefers: https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data#supported-formats
I raised #9274 to discuss this and received some good feedback.
I've now implemented JSON-LD support for the blog; both individual posts and the blog listing page. With this change in place, it's now possible to separately configure the Structured Data through swizzling the two new components:
BlogListPage/StructuredData
BlogPostPage/StructuredData
From @Josh-Cena:
The default behaviour for these components is to produce JSON-LD structured data that aligns with the Schema.org and Google's Rich Results guidelines.
Let's talk for a moment about each of these components.
BlogListPage/StructuredData
This component is responsible for generating the Structured Data for the blog list page. It renders JSON-LD structured data that aligns with the https://schema.org/Blog schema. (Please note the examples at the bottom of the page which this implementation aligns with.)
BlogPostPage/StructuredData
This component is responsible for generating the Structured Data for the blog post page. It renders JSON-LD structured data that aligns with the https://schema.org/BlogPosting schema. (Please note the examples at the bottom of the page which this implementation aligns with.)
The
BlogPosting
schema is one of the structured data types that Google explicitly supports for Rich Results: https://developers.google.com/search/docs/appearance/structured-data/article#structured-data-type-definitionsAll the Google-supported properties are included in the Structured Data generated by this component apart from
dateModified
which is optional. A number of other properties documented in theBlogPosting
schema are included as well.Test Plan
I will use the pull request preview on this PR to demonstrate that the Structured Data is generated as expected. I will also use the Structured Data Testing Tools to verify that the Structured Data is valid:
Expect screenshots to be added to this PR.Test links
Deploy preview: https://deploy-preview-9669--docusaurus-2.netlify.app/
BlogListPage/StructuredData
If we go to the test preview of the
/blog
page: https://deploy-preview-9669--docusaurus-2.netlify.app/blogWe can validate with schema.org that the Blog structured data is valid: https://validator.schema.org/#url=https%3A%2F%2Fdeploy-preview-9669--docusaurus-2.netlify.app%2Fblog
BlogPostPage/StructuredData
If we go to the test preview of the
/blog/releases/2.4/
page: https://deploy-preview-9669--docusaurus-2.netlify.app/blog/releases/2.4/We can validate with schema.org that the BlogPosting structured data is valid: https://validator.schema.org/#url=https%3A%2F%2Fdeploy-preview-9669--docusaurus-2.netlify.app%2Fblog%2Freleases%2F2.4%2F
And we can also test this type with the Rich Results tool: https://search.google.com/test/rich-results
You can also see this in the Ahrefs Chrome extension: https://chromewebstore.google.com/detail/ahrefs-seo-toolbar-on-pag/hgmoccdbjhknikckedaaebbpdeebhiei?pli=1
Related issues/PRs
#9274