henk
(Henk Valk)
June 2, 2020, 12:18pm
1
I'm new at VueJs.
I'm building a Portfolio website and want to add the page title and meta descriptions to the pages.
In the vue examples they are added as static content into the public/index.html.
Is there a way to get these fields from the Prismic Repo ?
Phil
(Phil Snow)
June 2, 2020, 12:43pm
2
Hi Henk,
Welcome to the community!
Yes, you can do this from your Prismic repo no problem.
First you’ll have to add the fields in your custom type and document in Prismic. We describe this here:
Though essentially you’ll just need to add some key text fields to add your seo title & descriptions etc.
Then because Vue creates an SPA, meaning you can add SEO tags to each view, you’ll need to use the Vue-Meta plugin:
This allows you to create an ‘Head’ seo object in your views. Then here you’ll pass in the content of your SEO fields from Prismic.
Let me know how this goes.
Thanks.
henk1
(Henk Valk)
June 9, 2020, 9:22pm
3
How do i get those key fields into the VueMeta? You have an example for this?
Phil
(Phil Snow)
June 10, 2020, 10:54am
4
Sure, essentially you need to query your different meta data fields and set them as variables, here I also used an or operator as a backup for empty fields:
this.meta.seo_title = document.data.seo_title || 'default title'
Then you need return the content in the data function.
data () {
return {
meta: {
seo_title: null
}
},
Finally Instead of defining metaInfo
as an object, define it as a function and access this
:
metaInfo () {
return {
title: this.meta.seo_title
}
},
Here’s a full example I prepared using our sample vue blog.
data () {
return {
dateOptions: { year: 'numeric', month: 'short', day: '2-digit' },
documentId: '',
meta: {
seo_title: null,
seo_description: null
},
fields: {
title: null,
date: null
},
slices: []
}
},
metaInfo () {
return {
title: this.meta.seo_title,
meta: [
{ vmid: 'description', name: 'description', content: this.meta.seo_description }
]
}
},
methods: {
getContent (uid) {
//Query to get post content
this.$prismic.client.getByUID('post', uid)
.then((document) => {
if (document) {
this.documentId = document.id
this.fields.title = document.data.title
this.fields.date = document.data.date
this.meta.seo_title = document.data.seo_title || 'default title'
this.meta.seo_description = document.data.seo_description || 'default description'
//Set slices as variable
this.slices = document.data.body
}
else {
//returns error page
this.$router.push({ name: 'not-found' })
}
})
}
},
Here’s the plugin’s doc’s on dynamic data and remember to pass the plugin to vue.use if you’re using the vue-router .
henk1
(Henk Valk)
June 11, 2020, 3:52pm
6
Thanks for your example
I added the Tab Social Cards
with the Slice
: general_card
fields: seo_title
, seo_description
and seo_image
in my JSON like your first example .
Because it’s a slice, I think it must be setup in the slice?
Your code is for the views/Blog.vue. So I must add the fields to the custom type, and not to a Slice.
Or can I add it to the App.vue so it’s not needed to add to each Custom Type in the Views folder ?
henk1
(Henk Valk)
June 11, 2020, 6:53pm
8
In my App.vue:
export default {
name: 'App',
metaInfo: {
title: 'Default Title',
titleTemplate: '%s - Company Name',
htmlAttrs: {
amp: true
}
},
When I add to my views/HomePage.vue
:
<script>
// imports for all components
import SlicesBlock from '../components/SlicesBlock.vue';
import Banner from "../components/Banner.vue"
export default {
name: 'home',
components: {
SlicesBlock,
Banner
},
data () {
return {
documentId: '',
fields: {
title: null,
page_title: null,
tagline: null,
image: null,
button_link: null,
button_label: null
},
slices: []
}
},
metaInfo () {
return {
title: this.fields.page_title,
}
},
methods: {
getContent () {
//Query to get home content
this.$prismic.client.getSingle('home')
.then((document) => {
if (document) {
this.documentId = document.id;
this.fields.page_title = document.data.page_title;
//Set slices as variable
this.slices = document.data.body
} else {
//returns error page
this.$router.push({ name: 'not-found' })
}
})
},
},
created () {
this.getContent()
}
}
</script>
my Window Title will display: [object Object] - Company Name
When I change the title to custom text:
metaInfo () {
return {
title: 'custom text',
titleTemplate: '%s - Company Name',
}
},
my Window Title will display: custom text - Company Name
I can’t find out why the variable isn’t showing up.
Edit:
My fault, I had a Title field instead of a Key Field. With the Key field it is working!!
Phil
(Phil Snow)
June 12, 2020, 11:01am
9
Yes, I should have made it clearer that using key text fields are easier to use here.
It seems you figured out that this needs to be done on the view
level, that’s good.
Did you figure out how to pass the data from the Slice to the metaInfo function?
henk
(Henk Valk)
June 12, 2020, 11:38am
11
In the example of the SEO tags & social cards the fields were RichTextFields instead of the Key text fields. When it’s on a slice level, the views template is much cleaner.
Only on view level indeed
I didn’t figure out how to get the data it in Slice…
When I share a link of the site, the default title and description in the public/index.html were shown. Do I need to remove the title and meta description in the public/index.html file?
Hi Phil
Do we have a similar concept using Next.js
Phil
(Phil Snow)
November 18, 2024, 10:29am
16
Hi @alshafaraz.gazi ,
You need to again add the fields in Prismic and query in your app:
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { asText } from "@prismicio/client";
import { SliceZone } from "@prismicio/react";
import { createClient } from "@/prismicio";
import { components } from "@/slices";
type Params = { uid: string };
export async function generateMetadata({
params,
}: {
params: Promise<Params>;
}): Promise<Metadata> {
const { uid } = await params;
const client = createClient();
const page = await client.getByUID("page", uid).catch(() => notFound());
return {
title: asText(page.data.title),
1 Like
@Phil Thanks bud.. I figured it out, and updated my layout.js and it worked like magic.
1 Like