Front-matter Vars, SEO and Social Tags
by John Pennock 7/10/2024
Review Front-matter Vars, SEO, and Social Tags Blog for a discussion about how these values are derived.
Basic Front-matter Vars
The basic template for the markdown content front-matter key:value pairs.
---
title: Template Title
description: "The Templates's description"
topic: General
isToc: true
createDate: 2024-05-03
createAuthor: Template Article Author in text, i.e. John Pennock
image: Social Image Link - ideally 1200 x 600 or 1200 x 630
imageAlt: Template Image Alt Text description
---
Complete Front-matter Vars
The complete template for the markdown content front-matter key:value pairs.
---
title: Template Title
description: "The Templates's description"
topic: General
isToc: true
version: 1.0 #optional for tracking
createDate: 2024-05-03 10:00:00
createAuthor: Template Article Author
createDate: 2024-05-03 10:00:00 # optional for when updated, createDate is required
createAuthor: Template Article Editor # optional, for second author
image: Template Image Link, ideally 2x1
imageAlt: Template Image Alt Text description
ogTitle: Template Open Graph Title
ogDescription: Template Open Graph Description
ogImage: Template Open Graph Image Link - ideally 1200 x 630
ogImageAlt: Template Open Graph Image Alt - use only if 'imageAlt' not sufficient
twitterTitle: Template Twitter Title
twitterDescription: Template Twitter Description
twitterImage: Template Twitter Image Link - ideally 1200 x 600 for large card, or 800 x 800 square for summary
twitterImageAlt: Template Twitter Image Alt - use only if 'imageAlt' not sufficient
twitterCard: Template Twitter Card - 'summary' (default) or 'summary_large_image'
twitterCreatorHandle: Template Twitter Creator handle, default @JohnPennock
---
app.vue
Default Global and Social
favicon.io - creation of favicons and webmanifest
<script setup>
const socialDefaults = {
siteName: 'Pennock Projects',
title: 'Pennock Projects',
description: 'Pennock Projects is a software engineering blog about front end frameworks, backend services, databases, and AI architecture by John Pennock',
rootUrl: "https://blog-mu-vert-29.vercel.app",
robots: 'index, follow',
copyright: '© 2024 by John Pennock',
type: 'article',
image2x1: '/images/PennockProjectsFB.jpg',
image1x1: '/images/PennockProjectsLogo.png',
imageAlt: 'Pennock Projects Logo',
twitterCard: 'summary_large_image',
twitterSite: '@PennockProjects',
twitterCreatorHandle: '@JohnPennock'
}
useHead({
titleTemplate: (titleChunk) => {
return (titleChunk && (titleChunk != socialDefaults.title)) ? `${titleChunk} - ${socialDefaults.title}` : socialDefaults.title;
},
htmlAttrs: {
lang: 'en'
},
link: [
{
rel: 'icon',
type: 'image/x-icon',
href: '/favicon.ico'
},
{
rel: 'apple-touch-icon',
sizes: '180x180',
type: 'image/png',
href: '/apple-touch-icon.png'
},
{
rel: 'icon',
sizes: '32x32',
type: 'image/png',
href: '/favicon-32x32.png'
},
{
rel: 'icon',
sizes: '16x16',
type: 'image/png',
href: '/favicon-16x16.png'
},
{
rel: 'manifest',
href: '/site.webmanifest'
},
{
rel: 'preconnect',
href: 'https://fonts.googleapis.com'
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap',
crossorigin: ''
}
]
})
// allow children components readonly access to social defaults.
provide("socialDefaults", socialDefaults);
// Setting Global SEO on each page
useSeoMeta({
robots: socialDefaults.robots,
copyright: socialDefaults.copyright
})
</script>
Page Dynamic SEO Social Tagging
This snippet shows steps necessary to dynamically update the header tags for this page.
<script setup>
const route = useRoute()
const socialDefaults = inject("socialDefaults");
const ogTitle = ref(socialDefaults.title)
const ogDescription = ref(socialDefaults.description)
const ogImage = ref(socialDefaults.image2x1)
const ogImageAlt = ref(socialDefaults.imageAlt)
const ogUrl = ref(socialDefaults.rootUrl)
const twitterTitle = ref(socialDefaults.title)
const twitterDescription = ref(socialDefaults.description)
const twitterImage = ref(socialDefaults.image2x1)
const twitterImageAlt = ref(socialDefaults.imageAlt)
const twitterCard = ref(socialDefaults.twitterCard)
const twitterCreatorHandle = ref(socialDefaults.twitterCreatorHandle)
// Canonical is in the head and not meta tags
useHead(() => ({
link: [
{
rel: 'canonical',
href: socialDefaults.rootUrl + route.path,
},
],
}))
useSeoMeta({
ogType: socialDefaults.type,
ogTitle: () => ogTitle.value,
ogDescription: () => ogDescription.value,
ogImage: () => ogImage.value,
ogImageAlt: () => ogImageAlt.value,
ogSiteName: socialDefaults.siteName,
ogUrl: () => ogUrl.value,
twitterTitle: () => twitterTitle.value,
twitterDescription: () => twitterDescription.value,
twitterImage: () => twitterImage.value,
twitterImageAlt: () => twitterImageAlt.value,
twitterCard: () => twitterCard.value,
twitterSite: socialDefaults.twitterSiteHandle,
twitterCreator: () => twitterCreatorHandle.value
})
const onDocReady = (doc) => {
let oTitle = (doc.ogTitle || doc.title)
let xTitle = (doc.twitterTitle || doc.title)
ogTitle.value = oTitle && oTitle != socialDefaults.title ? `${socialDefaults.title} ${oTitle}` : socialDefaults.title
ogDescription.value = doc.ogDescription || doc.description || socialDefaults.description
ogImage.value = doc.ogImage || doc.image || socialDefaults.image2x1
ogImageAlt.value = doc.ogImageAlt || doc.imageAlt || socialDefaults.imageAlt
ogUrl.value = socialDefaults.rootUrl + doc._path
twitterTitle.value = xTitle && xTitle != socialDefaults.title ? `${socialDefaults.title} ${xTitle}` : socialDefaults.title
twitterDescription.value = doc.twitterDescription || doc.description || socialDefaults.description
twitterImage.value = doc.twitterImage || doc.image || socialDefaults.image2x1
twitterImageAlt.value = doc.twitterImageAlt || doc.imageAlt || socialDefaults.imageAlt
twitterCard.value = doc.twitterCard || socialDefaults.twitterCard
twitterCreatorHandle.value = doc.twitterCreatorHandle || socialDefaults.twitterCreatorHandle
}
</script>
<template>
<ContentDoc>
<template v-slot="{ doc }">
{{ onDocReady(doc) }}
<article class="mx-auto">
{{ title }}
<ContentRenderer :value="doc" />
</article>
</template>
</ContentDoc>
</template>
Direct Front-matter Vars
---
head:
meta:
- name: 'keywords'
content: 'blog, John Pennock'
- name: 'robots'
content: 'index, follow'
- name: 'author'
content: 'John Pennock'
- name: 'copyright'
content: '© 2024 John Pennock'
- name: 'og:title'
content: 'Pennock Projects Blog'
- name: 'og:description'
content: 'Pennock Projects is a blog about software engineering by John Pennock'
- name: 'og:image'
content: '/images/PennockProjectsLogo.png'
- name: 'og:url'
content: 'https://blog-git-master-john-pennocks-projects.vercel.app/'
- name: 'twitter:title'
content: 'Pennock Projects Blog'
- name: 'twitter:description'
content: 'Pennock Projects is a blog about software engineering by John Pennock'
- name: 'twitter:image'
content: '/images/PennockProjectsLogo.png'
- name: 'twitter:card'
content: 'summary'
---