SEO matter's. With Gridsome, thank's to vue-meta, you can easely add open-graph, twitter and google tags.
This article is not about improving SEO, just add tags programmatically in your Gridosme project.
Tools
We need some tools for validate our SEO tags
Twitter Card Validator
Important
- you need a twitter account !
- work only with live site, not development mode
https://cards-dev.twitter.com/validator
Documentation: https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup
Google Data Structure Testing Tool
Important
Work in development mode, with some copy/paste...
https://search.google.com/structured-data/testing-tool
Global Metadatas
First we need to configure some basic metadatas, like siteUrl, siteName, etc..
module.exports = {
siteName: 'My Awesome Blog ',
siteDescription: 'Welcome to my Blog',
siteUrl: 'https:/www.mysite.com/',
metadata: {
author: 'John Doe',
twitter: '@johndoe',
// + whatever you want
},
...
}
All this metedatas are accessibles in any page or template, with a static-query
:
...
<static-query>
query { metadata { siteName siteDescription siteUrl author twitter } }
</static-query>
...
And then you can use it anywhere in the template, for example:
{
property: 'og:url',
content: this.$static.metadata.siteUrl
},
Blog posts
Assume you have a template, BlogPost.vue
for exemple.
His structure is something like this:
<template>
...
</template>
<page-query>
...
</page-query>
<static-query>
query { metadata { siteName siteDescription siteUrl } }
</static-query>
<script>
import ...
export default {
...
}
</script>
Focus on the basic structure of meta datas:
export default {
components: {
...
},
metaInfo() {
return {
title: this.$page.blog.title, //for example
meta: [
// Regular meta tags
...
// open-graph tags
...
// twitter card
...
],
// Some ld+json tags
script: [
{
type: 'application/ld+json',
json: {
...
}
}
]
}
}
}
With a complete example:
metaInfo() {
return {
title: this.$page.blog.title,
meta: [
{
name: 'description',
content: this.$page.blog.description
},
// open-graph tags
{
property: 'og:title',
content: this.$page.blog.title
},
{
property: 'og:description',
content: this.$page.blog.description
},
{
property: 'og:image',
content: this.$page.blog.cover_image || ''
},
{
property: 'og:url',
content: this.$static.metadata.siteUrl + this.$page.blog.path
},
// twitter card
{
name: 'twitter:card',
content: this.$page.blog.cover_image
? 'summary_large_image'
: 'summary'
},
{
name: 'twitter:creator',
content: this.$page.blog.author.twitter
},
{ name: 'twitter:title', content: this.$page.blog.title },
{ name: 'twitter:description', content: this.$page.blog.description }
],
// Some ld+json tags
script: [
{
type: 'application/ld+json',
json: {
'@context': 'http://schema.org',
'@type': 'BlogPosting',
description: this.$page.blog.description,
datePublished: this.$page.blog.datePublished,
dateModified: this.$page.blog.dateModified,
author: {
name: this.$page.blog.author.name
},
headline: this.$page.blog.title,
image: this.$page.blog.cover_image,
mainEntityOfPage: {
'@type': 'WebPage',
'@id': this.$static.metadata.siteUrl + this.$page.blog.path
}
}
}
]
}
}
You need to adapt your queries, and your frontmatter in order to match the SEO fields.
Tip
If you're the only one author of your blog, you can hard-code your meta data.
Frontmatter and page queries
In order to match with the previous config with open-graph tags, twitter card tags and ld+json tags, you must adapt the frontmaters of your blog posts.
For example:
---
published: true
date: 2020-25-02
datepublished: 2020-02-25T19:31:47Z
datemodified: 2020-02-25T21:19:16Z
category: dev
author:
name: John Doe
twitter: @johndoe
title: Hello World !
tags: seo, Gridsome
description: lorem ipsum
cover_image: https://res.cloudinary.com/dpw19qolx/image/upload/v1562052876/nebulae-1199180_1920.jpg
cover_image_caption: Nebulae from Unsplash
---
bla bla bla
And the page query:
<page-query>
query($id: ID!, $previousElement: ID!, $nextElement: ID!) { blog(id: $id) {
title path cover_image cover_image_caption description content date :
date(format:"DD MMMM YYYY") datePublished : date(format:"ddd MMM DD YYYY
hh:mm:ss zZ") dateModified : date(format:"ddd MMM DD YYYY hh:mm:ss zZ")
timeToRead tags { id title path } author { name twitter } } }
</page-query>