-
-
Notifications
You must be signed in to change notification settings - Fork 8k
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 <sidachen2003@gmail.com>
…turedData/index.tsx Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
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! |
Hey @slorber, It's been two weeks - just wanted to check in and see how the "amélioration" section of Docusaurus Google Search Console is looking? Does it look okay? |
So far it doesn't seem to affect SEO much. But I'll keep monitoring this for a few more weeks to be sure. Impressions (purple) have slightly decreased, but it could be seasonality, Google algorithm changes, or something else 🤷♂️ Surprisingly the number of clicks (blue) remains as high as before so maybe the search just became more relevant? Do you observe similar behavior on your site? We still have the same breadcrumbs suggestions being reported: |
I suspect this is just slight variability - essentially SEO unaffected. If things change massively then it's a concern; slight variance then it's likely just fine. (SEO will always vary slightly over time and that's out of our control in the main and nothing to worry about)
have you done anything to remedy this? I didn't spot a PR but I might have missed. TL;DR - so far it sounds fine |
Agree 👍 I still want to work on a few things for v3.2 so maybe we'll include this PR in v3.2 in a few weeks.
Not a high priority for me to investigate atm, I'll get back to it later so if you know how to fix the problem go ahead. We have this being reported for docs and blog posts too. Not sure why I can't get this UI in English easily 😅
|
I'm pretty snowed right now, but I might see if I can take a look in a couple of weeks when things quiet down (I hope) |
Looks good - ship it! |
Great work on this @johnnyreilly. Is the change live? I don’t see it in the changelog. |
I think it went live with 3.2 |
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