-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
feat: add metatags support for seo / blogposts #5373 #5375
Conversation
✔️ [V2] 🔨 Explore the source changes: e59c59a 🔍 Inspect the deploy log: https://app.netlify.com/sites/docusaurus-2/deploys/611fb356d20fcf0008a7a8e2 😎 Browse the preview: https://deploy-preview-5375--docusaurus-2.netlify.app |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-5375--docusaurus-2.netlify.app/ |
packages/docusaurus-theme-classic/src/theme/BlogPostItem/index.tsx
Outdated
Show resolved
Hide resolved
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.
This works but I'd prefer another implementation
@@ -132,6 +132,7 @@ declare module '@theme/Seo' { | |||
readonly description?: string; | |||
readonly keywords?: readonly string[] | string; | |||
readonly image?: string; | |||
readonly metaTags?: Record<string, string>; |
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.
Honestly, I'm not a fan of using the SEO component for all use-cases but I'd rather keep it small and not increase this API.
Head/helmet is here to handle other use-cases
Also, metas can be property/name (difference matter afaik):
Using Record<string,string>
is confusing, less explicit and can only handle one of those 2 cases so it's an error-prone abstraction.
I'd rather use <Head>
in BlogPostItem even if this feels duplicate with <Seo>
.
Eventually:
- add a generic
children
prop to pass additional head elements inside<Seo>
? - let
Seo
accept anyHead
prop and spread them? (it has ameta
prop btw)
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.
Okay cool - just pushed a different implementation based upon your feedback. Does that look kind of like what you had in mind?
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.
Yes, that looks better to me :)
Another thing to consider: this comp is used in the paginated list view.
This means that on this page: https://deploy-preview-5375--docusaurus-2.netlify.app/blog/
We have 3 times those metas being declared in <Head>
, and the last article of the list "wins".
I'm not sure it's what you want in this case. Unlike structured data, page metas override each others.
We have a isBlogPostPage
prop on this comp that you could use.
(I don't like it much, it's error-prone as we can see here, and I'd rather use composition and have a dedicated comp for the list blog post item)
Note: I'm not sure Head supports React fragments well 🤪
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.
We have a isBlogPostPage prop on this comp that you could use.
Done!
)} | ||
</Seo> | ||
) : ( | ||
<Seo {...{keywords, image}} /> |
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.
I think we shouldn't need that either and is probably a mistake?
It doesn't make sense to me to render the meta keywords of the last blog post of the list 🤪
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.
What about just moving this Seo comp to BlogPostPage?
The list should have totally different metadata than a single blog post imho
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.
So I wanted SEO to continue doing what it did before... Are you saying you'd like to remove the SEO component entirely from this page? As I didn't add it there; it was already present.
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.
The change as implemented right now renders the SEO component as it already is in the case that this is not a isBlogPostPage
, and in the case where it is, it renders the SEO component with the child meta tags.
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.
So the current implementation is this:
<Seo {...{keywords, image}} />
With the changes in this PR that will still be rendered in the case where isBlogPostPage === false
When it is true it will render:
<Seo {...{keywords, image}}>
<meta property="og:type" content="article" />
<meta property="article:published_time" content={date} />
{authorURL && <meta property="article:author" content={authorURL} />}
{frontMatter.tags && (
<meta property="article:tag" content={frontMatter.tags.join(',')} />
)}
</Seo>
If we pull Seo
entirely from this component then presumably that breaks other use cases?
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.
I guess we could just put Seo back to how it was before and do this in BlogPostPage
:
<Head>
<meta property="og:type" content="article" />
<meta property="article:published_time" content={date} />
{authorURL && <meta property="article:author" content={authorURL} />}
{frontMatter.tags && (
<meta property="article:tag" content={frontMatter.tags.join(',')} />
)}
</Head>
Would that work?
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.
Implemented this approach. That what you had in mind?
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.
🤪
So I wanted SEO to continue doing what it did before... Are you saying you'd like to remove the SEO component entirely from this page?
Yes that's exactly what I mean: what we already do is incorrect and should be fixed, so this PRR is a good opportunity to do so :)
https://socialsharepreview.com/?url=https://docusaurus.io/blog
=> we should probably not display the social card + keywords of the last blog post of the list here.
Just move Seo
to BlogPostPage
instead (even if it's not as before)
It does not make much sense to me anyway to declare SEO metadata on reusable comps that can be useful in both list+details pages.
Metadatas should preferably be handled at the page entry-point level: BlogListPage
+ BlogPostPage
, not BlogPostItem
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.
Okay cool - I'm away from my keyboard the next couple of weeks. If you'd like to work on this branch in the meantime please feel free. If not I can take a look when I'm back!
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.
fixed :)
This reverts commit 1cba459
Motivation
See #5373
Docusaurus does not provide
og:type
at present. It would be good if it did; perhaps with a value ofwebsite
orarticle
. eg:This PR provides that support through a generic meta tags mechanism which is used only by the blog mechanism at present. Blogs get the
og:type
ofarticle
as well as some article data, powered by the metadata available:Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
Building and running locally you can see the new tags being generated:
Also visible in the preview:
Related PRs
N/A