Social Sharing Meta Tags in Vue

Configure Open Graph and Twitter Card meta tags for rich link previews on Facebook, X/Twitter, LinkedIn, Slack, and Discord.
Harlan WiltonHarlan Wilton12 mins read Published Updated
What you'll learn
  • OG tags control social previews on Facebook, LinkedIn, Slack, Discord
  • Images must be absolute HTTPS URLs (not relative paths)
  • Twitter/X requires twitterCard—there's no fallback from OG tags

Social platforms use Open Graph (OG) and Twitter Card meta tags to generate link previews. Without them, shared links appear as plain text.

SSR required: Social crawlers don't run JavaScript. Your meta tags must be in the initial HTML response, which means server-side rendering or prerendering.

<script setup lang="ts">
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',
  // Twitter/X (required - no OG fallback for card type)
  twitterCard: 'summary_large_image'
})
</script>

Quick Tips

  1. Images matter: Posts with optimized OG images see 40-60% higher click-through rates. Images must be absolute URLs, minimum 1200x630px.
  2. Social titles can differ: Your og:title doesn't have to match your page title. Use casual, provocative language for social—it's not search.
  3. Always set twitterCard: X/Twitter has no fallback for card type. Skip it and you get plain text.

Open Graph Tags

Use useSeoMeta() for OG tags—it handles the property attribute automatically.

Core Tags

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.
})

Image Requirements

SpecValue
Minimum size1200x630px (1.91:1 ratio)
Max file size5MB (1MB recommended)
FormatsJPG, PNG, WebP, GIF
URLAbsolute HTTPS

Include dimensions for faster rendering:

useSeoMeta({
  ogImage: 'https://mysite.com/og-images/preview.jpg',
  ogImageAlt: 'Product preview showing 3 stacked boxes',
  ogImageWidth: 1200,
  ogImageHeight: 630,
  ogImageType: 'image/jpeg'
})
OG images must use absolute URLs with HTTPS. Relative paths like /images/og.png won't work—social crawlers don't know your domain. Always include the full URL: https://mysite.com/images/og.png

Article Metadata

For blog posts, add article-specific tags:

useSeoMeta({
  ogType: 'article',
  articleAuthor: ['Harlan Wilton'],
  articleSection: 'SEO Tutorials',
  articleTag: ['vue', 'seo', 'meta-tags'],
  articlePublishedTime: '2024-11-05T00:00:00Z',
  articleModifiedTime: '2025-12-17T00:00:00Z'
})

Twitter/X Cards

X requires its own twitter:* meta tags. Without twitter:card, your links appear as plain text—no image, no description.

Card Types

summary_large_image — Full-width image. Use this for most pages.

useSeoMeta({
  twitterCard: 'summary_large_image',
  twitterImage: '/preview.jpg' // 2:1 ratio, min 300x157px
})

summary — Small square thumbnail. For compact previews.

useSeoMeta({
  twitterCard: 'summary',
  twitterImage: '/icon.jpg' // 1:1 ratio, min 144x144px
})

player and app cards require approval from X.

X Fallbacks

X falls back to Open Graph when twitter:* equivalents are missing:

Twitter TagFallback
twitter:titleog:title
twitter:descriptionog:description
twitter:imageog:image

twitter:card has no fallback—skip it and you get no card.

Minimal setup using fallbacks:

useSeoMeta({
  twitterCard: 'summary_large_image', // required
  ogTitle: 'My page',
  ogImage: 'https://mysite.com/image.jpg'
})

Optional Twitter Tags

useSeoMeta({
  twitterSite: '@yourhandle', // Site's X handle
  twitterCreator: '@authorhandle', // Author's handle
  twitterImageAlt: 'Alt text' // 420 chars max
})

Slack & Discord

Both platforms read Open Graph tags. No platform-specific tags needed.

useSeoMeta({
  ogTitle: 'Dashboard Analytics',
  ogDescription: '847 active users, 12.4% conversion rate',
  ogImage: 'https://mysite.com/og/dashboard.png'
})

Slack also reads Twitter Card tags as fallback. Discord supports animated GIFs and shows real-time previews.

Slack-Specific Behavior

  • Cache: ~30 minutes globally
  • Ignores: og:type, og:locale, article:* tags, Schema.org
  • No redirect following for images—use direct URLs

Platform Cache Times

PlatformCache DurationClear Cache
Facebook14-30 daysSharing Debugger
LinkedIn7 daysPost Inspector
X/Twitter~7 daysAdd ?v=2 to URL
Slack~30 minutesAdd ?v=2 to URL
DiscordReal-timeNo cache

Dynamic Meta Tags

Data must be available during server render—onMounted runs too late for crawlers.

// 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">
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 Tools

  1. Facebook Sharing Debugger — Also validates OG tags for Slack
  2. LinkedIn Post Inspector
  3. X/Twitter — Compose a tweet (don't post) to see preview
  4. Discord — Paste link for real-time preview

Troubleshooting

Image not showing

  • URL must be absolute HTTPS (not relative)
  • File under 5MB
  • Image returns 200 (not redirect)
  • Not blocked by robots.txt

Wrong title/description

  • Platform cached old version—add ?v=2 to URL
  • For X: check you're setting twitterCard

Card not appearing at all

  • Missing twitterCard for X (no fallback)
  • Page requires auth (crawlers can't log in)

OG Image Tools

Creating OG images manually is tedious:

Using Nuxt?

Nuxt SEO handles social sharing automatically with the OG Image module.

Learn more about Social Sharing in Nuxt →