Complete AI Training
Sign inBecome a member

Your job's AI kit

Get your AI kit

Tell us who you are and what you do. We show you your kit right away and email you the link: skills, prompts, AI agents, MCP servers and courses for your job.

500+ jobs ready, and we make a kit for any other job. No payment needed to look.

Share

Skill · SEO

Social metadata hardening

Fix social sharing previews so URLs render as rich cards on Facebook, LinkedIn, X/Twitter, WhatsApp, Telegram, and more. Covers OG tags, Twitter cards, absolute image URLs, and debugging.

Agentic Awesome SkillsAdded Sep 5, 2026
Use it in my AI

How to use it

  1. Start your plan and connect your AI once
  2. Add the skill to your AI, one time only: press Copy skill and paste it into your AI's instructions: a project in ChatGPT, Claude or Grok, a Gem in Gemini, an agent in Microsoft 365 Copilot, or a rule in Cursor. It stays there for every new chat. In Kimi, paste it at the start of a new chat.
  3. Ask for the task in your own words, or say it directly:
Use the Social metadata hardening skill to help me with this.
SKILL.md

Social Metadata Hardening Skill

Fix social sharing so every important URL unfurls as a rich card across all platforms.


When to Use

  • Use when shared links show missing, stale, cropped, or incorrect previews on social and chat platforms.
  • Use when auditing Open Graph, Twitter/X card, image URL, alt text, or metadataBase coverage in a web app.
  • Use before launch when every public page needs predictable rich previews across LinkedIn, X, Facebook, WhatsApp, Slack, Discord, and Telegram.

Why Previews Break

ProblemRoot Cause
No preview at allMissing og:title, og:description, or og:image
Broken imageRelative URL (must be absolute)
Wrong image sizeImage not 1200×630px (OG standard)
Plain text cardTwitter card type missing or set to summary
Stale previewPlatform caching old metadata
Metadata missing on crawlTags added by client-side JS (crawlers don't run JS)

The Gold Standard Metadata Block

Every shareable page needs ALL of these in static HTML:

// Next.js App Router — lib/socialMetadata.js
export function buildSocialMetadata({
  title,
  description,
  path,          // '/blog/my-post'
  image,         // '/images/og/my-post.jpg' or full URL
  imageAlt,
  imageWidth = 1200,
  imageHeight = 630,
}) {
  const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://www.yourdomain.com';
  
  // Always produce an absolute URL
  const imageUrl = image?.startsWith('http') ? image : `${baseUrl}${image}`;
  const pageUrl  = `${baseUrl}${path}`;
  
  // Detect MIME type from extension
  const ext = imageUrl.split('.').pop().toLowerCase();
  const mimeMap = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', webp: 'image/webp' };
  const imageType = mimeMap[ext] || 'image/jpeg';

  return {
    title,
    description,
    alternates: { canonical: pageUrl },
    openGraph: {
      title,
      description,
      url: pageUrl,
      type: 'website',  // use 'article' for blog posts
      images: [{
        url: imageUrl,
        secureUrl: imageUrl,   // explicit HTTPS version
        width: imageWidth,
        height: imageHeight,
        alt: imageAlt || title,
        type: imageType,
      }],
    },
    twitter: {
      card: 'summary_large_image',  // NOT 'summary' — that shows a tiny image
      title,
      description,
      images: [imageUrl],
    },
  };
}

Applying the Helper

Static page

// app/about/page.js
import { buildSocialMetadata } from '@/lib/socialMetadata';

export const metadata = buildSocialMetadata({
  title: 'About Us | My Site',
  description: 'Learn about our team and mission.',
  path: '/about',
  image: '/images/og/about.jpg',
  imageAlt: 'The My Site team',
});

Dynamic page (blog post, tool page)

// app/blog/[slug]/page.js
import { buildSocialMetadata } from '@/lib/socialMetadata';

export async function generateMetadata({ params }) {
  const post = await getPost(params.slug);
  return buildSocialMetadata({
    title: `${post.title} | My Blog`,
    description: post.excerpt,
    path: `/blog/${params.slug}`,
    image: post.ogImage || '/images/og/default.jpg',
    imageAlt: post.title,
  });
}

Homepage (app/layout.js or app/page.js)

export const metadata = {
  metadataBase: new URL('https://www.yourdomain.com'), // REQUIRED for absolute URLs
  ...buildSocialMetadata({
    title: 'My Site — Tagline Here',
    description: 'Site-wide description.',
    path: '/',
    image: '/images/og/home.jpg',
  }),
};
⚠️ Set metadataBase when using relative metadata URLs. If your helper already outputs absolute canonical/OG URLs, previews can still work without it.

OG Image Checklist

Good OG images:

  • 1200 × 630px (2:1 ratio — works on all platforms)
  • Under 8MB (Facebook limit)
  • Served over HTTPS
  • File name has no spaces (use hyphens)
  • Format: JPEG or PNG (WebP works on most but not all crawlers)
  • Accessible via GET with no authentication
# Verify your OG image is reachable and correct size
curl -sI https://www.yourdomain.com/images/og/home.jpg | grep -i "content-type\|content-length\|status"

Platform-Specific Notes

Facebook / Meta

  • Caches aggressively — use the Sharing Debugger to force recrawl
  • Minimum image: 200×200px (but use 1200×630 for quality)
  • Needs: og:title, og:description, og:image, og:url

X / Twitter

  • Use twitter:card = summary_large_image for full-width images
  • twitter:image must be an absolute URL
  • Use the Card Validator to test

LinkedIn

  • Caches hard — use Post Inspector to refresh
  • Respects og: tags; ignores twitter: tags
  • Image must be ≥1.91:1 aspect ratio

WhatsApp / Telegram

  • Read OG tags on first share; cache can last hours
  • Re-share after a few hours for the cache to clear naturally

Slack / Discord

  • Both use OG tags; both cache
  • Discord also supports og:type = article for richer embeds

Debugging Social Previews

1. Check raw HTML for tags

curl -s https://www.yourdomain.com/blog/my-post | grep -i "og:\|twitter:"

If tags don't appear → they're being added by JavaScript (not crawlable). Fix: move to export const metadata or generateMetadata.

2. Validate with platform tools

PlatformTool
Facebookhttps://developers.facebook.com/tools/debug/
LinkedInhttps://www.linkedin.com/post-inspector/
Twitter/Xhttps://cards-dev.twitter.com/validator
Generalhttps://metatags.io

3. Force cache refresh

After deploying fixes, paste the URL into each platform's debugger and click "Fetch new scrape information" (or equivalent).


Social Metadata Checklist

  • [ ] metadataBase set in root layout
  • [ ] All shareable pages use shared buildSocialMetadata helper
  • [ ] OG image URLs are absolute (start with https://)
  • [ ] secureUrl set equal to url in OG image block
  • [ ] Image is 1200×630px, under 8MB, HTTPS
  • [ ] twitter:card is summary_large_image (not summary)
  • [ ] Image alt text present
  • [ ] Tags visible in raw HTML (not JavaScript-rendered)
  • [ ] All platform debuggers show correct preview
  • [ ] Cache refreshed on all platforms after deployment

Limitations

  • Cannot force immediate cache refresh on every social platform; some previews may remain stale after a correct fix.
  • Requires publicly reachable deployed URLs for reliable validation with platform debuggers.
  • Does not replace brand, accessibility, or legal review of image text, alt text, and preview copy.