Social Sharing Meta Tags in Vue
- OG tags control social previews on Facebook, LinkedIn, Slack, Discord
- Use absolute HTTPS image URLs for reliable access
- Set
twitterCardexplicitly and test the preview on X
Social platforms use Open Graph (OG) and Twitter Card meta tags to generate link previews. Missing or inaccessible tags can produce incomplete previews.
Initial HTML required: Put social tags in the response a platform fetches. Static HTML, prerendering, and server-side rendering can all provide them.
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
// Open Graph (Facebook, LinkedIn, Discord, Slack)
ogTitle: 'Your page title',
ogDescription: 'Short description',
ogImage: 'https://mysite.com/og.png',
ogUrl: 'https://mysite.com/page',
// Set the X card layout explicitly
twitterCard: 'summary_large_image'
})
</script>Quick Tips
- Images matter: a public
og:imagegives platforms a preview image to use. The resulting layout depends on the platform. Images must be absolute URLs. - Social titles can differ: your
og:titledoesn't have to match your page title. Search intent doesn't apply on social, so casual or provocative language works fine. - Set
twitterCardexplicitly: Choose the card layout and test it on X.
Open Graph Tags
Use useSeoMeta() for OG tags: it handles the property attribute automatically.
Core Tags
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
ogTitle: 'Hey! Open graph images are important.',
ogDescription: 'But who reads the description anyway?',
ogImage: 'https://mysite.com/og.png', // must be absolute URL
ogUrl: 'https://mysite.com/products/item', // canonical URL
ogType: 'website' // or 'article', 'product', etc.
})
</script>Image Requirements
Check each platform's image requirements. A 1200×630 image is a useful starting point. Preview cropping can differ. Test important images on the platforms your readers use.
Include metadata describing the image dimensions:
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
ogImage: 'https://mysite.com/og-images/preview.jpg',
ogImageAlt: 'Product preview showing 3 stacked boxes',
ogImageWidth: 1200,
ogImageHeight: 600,
ogImageType: 'image/jpeg'
})
</script>https://mysite.com/images/og.pngArticle Metadata
For blog posts, add article-specific tags:
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
ogType: 'article',
articleAuthor: ['Harlan Wilton'],
articleSection: 'SEO Tutorials',
articleTag: ['vue', 'seo', 'meta-tags'],
articlePublishedTime: '2024-11-05T00:00:00Z',
articleModifiedTime: '2026-07-16T00:00:00Z'
})
</script>Twitter/X Cards
Set X card metadata explicitly when you need a specific layout. Preview behavior can depend on the platform and cached metadata.
Card Types
summary_large_image: Full-width image. Use this for most pages.
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
twitterCard: 'summary_large_image',
twitterImage: 'https://mysite.com/preview.jpg' // Check the current X large-image requirements
})
</script>summary: Small square thumbnail. For compact previews.
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
twitterCard: 'summary',
twitterImage: 'https://mysite.com/icon.jpg' // Check the current X summary-image requirements
})
</script>player and app cards have additional platform requirements. Check X's current guidance before choosing them.
X Fallbacks
Set platform-specific tags when your X preview must differ. Test the preview with the current platform. The former X card markup documentation now redirects to a generic developer overview.
An explicit title and image setup:
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
twitterCard: 'summary_large_image',
ogTitle: 'My page',
ogImage: 'https://mysite.com/image.jpg',
twitterTitle: 'My page',
twitterImage: 'https://mysite.com/image.jpg'
})
</script>Optional Twitter Tags
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
twitterSite: '@yourhandle', // Site's X handle
twitterCreator: '@authorhandle', // Author's handle
twitterImageAlt: 'Alt text'
})
</script>Slack & Discord
Both platforms read Open Graph tags directly, no platform-specific tags needed.
<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
ogTitle: 'Dashboard Analytics',
ogDescription: '847 active users, 12.4% conversion rate',
ogImage: 'https://mysite.com/og/dashboard.png'
})
</script>Check Slack and Discord previews after changing tags or images. Each platform can cache its own copy.
Platform behavior can change. Check the preview instead of relying on an exact cache lifetime.
Platform Cache Times
Platforms cache metadata. Use Facebook Sharing Debugger or LinkedIn Post Inspector to request a refresh where supported. Recheck the preview after updates. A query parameter can create a different URL, but it does not guarantee cache invalidation.
Dynamic Meta Tags
Data must be available while generating the initial HTML. These excerpts show data flow only. Your SSR entry must also install Unhead, render the Vue app, and insert the rendered head tags. onMounted does not run during SSR.
// entry-server.ts
export async function render(url: string) {
const product = await fetch(`https://api.mysite.com/product/${url}`).then(r => r.json())
const app = createSSRApp(App)
app.provide('product', product)
return { app, product }
}<script setup lang="ts">
import { useSeoMeta } from '@unhead/vue'
import { inject } from 'vue'
const product = inject <Product> ('product')
useSeoMeta({
ogTitle: product?.name,
ogDescription: product?.shortPitch,
ogImage: `https://mysite.com/api/og?title=${encodeURIComponent(product?.name || '')}`,
twitterCard: 'summary_large_image'
})
</script>Testing & Troubleshooting
Test previews before you ship:
- Facebook Sharing Debugger: Check Facebook's fetch and preview
- LinkedIn Post Inspector
- X/Twitter: Compose a tweet (don't post) to see preview
- Discord: Paste link for real-time preview
Image not showing
- URL must be absolute HTTPS (not relative)
- File meets the target platform's current limits
- Image is publicly accessible at its final URL
- Not blocked by robots.txt
Wrong title/description
- Platform may have cached an old version. Use its refresh tool where available
- For X: check your card metadata and the current preview
Card not appearing at all
- Missing or inaccessible card metadata
- Page requires auth (crawlers can't log in)
OG Image Tools
Creating OG images manually is tedious:
- OG Image Playground: Design and export with code
- x-satori: Vue SFCs + Tailwind to generate at build time
Checklist
- Set
ogTitle,ogDescription,ogImage, andogUrlwithuseSeoMeta()from@unhead/vue - Use an absolute HTTPS URL for
ogImage, with dimensions suited to your target platforms - Set
twitterCardexplicitly and test the X preview - Fetch data before render (not in
onMounted()) so crawlers see it - Test previews with the Facebook Sharing Debugger, LinkedIn Post Inspector, or the Social Share Debugger
Using Nuxt? Nuxt SEO handles social sharing automatically with the OG Image module. Learn more about Social Sharing in Nuxt →
Pre-launch setup, post-launch verification, and ongoing monitoring. Interactive checklist with links to every guide.