-
Notifications
You must be signed in to change notification settings - Fork 4.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
Set Metadata on component level #2153
Comments
Thanks for filing this @samanthaming! We really appreciate the time and effort you took to investigate this and will add this our list of items to discuss for our roadmap! Would you be interested in code pairing sometime so I can get a better understanding of the problem and your current solution? |
Thanks @bencodezen for looking into this 👏 Absolutely! I'll reach out to you and we can set something up 🙌 |
To follow up on @samanthaming's comment, I also wrote a custom plugin that injects metadata into the |
@adamdehaven wooo you have a custom plugin 🤩 is it an open source that you can provide a link to? Would love to check it out 😊 |
@samanthaming I haven't released it yet, but plan to (still doing a little testing). I just redesigned my site with VuePress as well and am getting ready to push the site itself live in the coming days. The plugin I wrote injects the canonical URL, Schema.org structured data, as well as extra metadata into the ssrTemplate during the build process (so the tags will not be present when running |
@bencodezen I may (huge question mark here) have found a somewhat easy way to implement part of the ask here (canonical URL tag), which could likely be expanded to allow for dynamic injection. If the check for // vuepress/packages/@vuepress/core/lib/client/root-mixins/updateMeta.js
export default {
// created will be called on both client and ssr
created () {
this.siteMeta = this.$site.headTags
// .filter(([headerType]) => headerType === 'meta') // OLD
.filter(([headerType]) => ['meta', 'link'].includes(headerType)) // NEW: allows for 'meta' and 'link' tags
.map(([_, headerValue]) => headerValue)
// ... more code Then, in a page's frontmatter: ---
# Defining page-level metadata - unchanged (goes back to original request to allow for dynamic metadata)
meta:
- name: description
content: Page description text
# Defining other link data (although the requested link in Issues is currently canonical URL)
link:
- href: https://www.example.com/canonical/url/link/
rel: canonical
--- This still requires the values be hard-coded into the frontmatter; however, is an easy way to expand the type of tag that can be injected via frontmatter. The problem with other canonical URL solutions (as well as injecting metadata) is that they only load for the current page and then are not updated dynamically (as in the build process, not client-side) as the pages change. The correct URLs display in the created() {
if (typeof this.$ssrContext !== "undefined") {
this.$ssrContext.userHeadTags += `\n <link rel="canonical" href="${this.computeURL()}"/>`;
}
} This only loads the proper URL (or other content) for the first-requested page. Any subsequent navigation within the VuePress SPA does not update the properties, even if you watch |
@adamdehaven Great research! Would you be interested in opening up a PR on this? In the long run, we probably need to find a way to integrate vue-meta as its API is fairly ubiquitous in the Vue community these days. Hoping to get to this at some point, but your solution seems to be a great way to open up possibilities in the meantime. Let me know what you think! |
@bencodezen integrating I should be able to submit a PR; however, I'm traveling and it may be next week. Question: would implementing the way I suggested above also open up the properties to the If I allow script tags as well, and wanted to include JSON as the content (instead of adding an attribute) how would this be structured in YAML? |
@adamdehaven No worries as far as urgency. In the event I manage to get a head start, I'll be sure to update the thread so you're aware 👍 In regards to your question, I inherited the project after its release, so I'm still learning the ins and outs of the codebase. If you discover the answer to this before I do, would love to get your findings documented so other people have an easier time contributing in the future! |
Started my cursory overview of this and had a few quick questions here: Would we want to implement If moving to If the answer isn't vue-meta, then would we try to implement our own API? I'm not too keen on this one as it seems to reinvent the wheel with the added bonus maintenance for the VuePress team Any and all feedback/dialogue is welcome! |
@d-pollard I think implementing |
@adamdehaven - thanks for the feedback From what I've read on I'm concerned, however, with how we'd introduce |
@d-pollard so just thinking out loud, but here goes: What if VuePress included
If VuePress does do something to this effect, I strongly plead for a way to also include a page's Edit: spelling is hard. |
@adamdehaven - since the canonical bit was a quick win here, I've opened this PR: #2658 Mind reviewing it and giving your thoughts for me? |
Update: Moving comments to PR #2658 |
@adamdehaven - my apologies, I forgot to commit my most recent change; please try again with the newest changes |
@d-pollard moving the PR conversation to #2658 thread 😄 |
This PR introduces Vue Meta: #2661 it is a backwards compatible replacement for current setup, please add any questions or concerns in that thread |
Feature request
Currently the way to set custom metadata is through the frontmatter in the markdown file. It'd be very helpful if we could set this on the component level.
The Problem
Here's a scenario of why this is important. I use Cloudinary to store my images and I use a gulp task to upload the images. Which then populates a single javascript object with all of the ID of the images. These are the images I want to use in my meta head (especially for my social media links on twitter and facebook). And I really don't want to set them manually in each of my markdown frontmatter.
Ideal Solution
It'd be so nice, if I could set the meta head directly in my layout or component. Something like vue-meta from Nuxt.
Alternative Solution
Unfortunately, I had trouble trying to figure out how to set the
vue-meta
plugin to work with VuePress via the SSR way. So instead I created a custom plugin that will programmatically set the frontmatter withfrontmatter.meta
. It's working in my dev environment, however, when the site is built, it then has duplicates (I just found this out and have not looked into it yet, when I find out why, I'll update this issue).Conclusion
I know VuePress is mainly built for technical documentation. But for those using it for more than that, I think meta data is a super important feature. I used VuePress to build my blog and I picked a static site generator for SEO reason. And meta data is an integral part of that.
Overall I loved using VuePress to build my new site (the markdown support and the built-in header search are amazing!). All that's missing is this meta data support. Not trying to compare VuePress to others, but Gridsome offers this. And it's probably one of the feature that might make me want to switch over.
Anyways, I think the team did a fabulous job on this. I hope you will consider this feature! 👏
The text was updated successfully, but these errors were encountered: