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.

5 stars

Best use case

social-metadata-hardening is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

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.

Teams using social-metadata-hardening should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/social-metadata-hardening/SKILL.md --create-dirs "https://raw.githubusercontent.com/FrancoStino/opencode-skills-collection/main/bundled-skills/social-metadata-hardening/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/social-metadata-hardening/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How social-metadata-hardening Compares

Feature / Agentsocial-metadata-hardeningStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

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.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# 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

| Problem | Root Cause |
|---------|-----------|
| No preview at all | Missing og:title, og:description, or og:image |
| Broken image | Relative URL (must be absolute) |
| Wrong image size | Image not 1200×630px (OG standard) |
| Plain text card | Twitter card type missing or set to `summary` |
| Stale preview | Platform caching old metadata |
| Metadata missing on crawl | Tags 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:

```js
// 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
```js
// 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)
```js
// 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)
```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

```bash
# 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](https://developers.facebook.com/tools/debug/) 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](https://cards-dev.twitter.com/validator) to test

### LinkedIn
- Caches hard — use [Post Inspector](https://www.linkedin.com/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
```bash
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

| Platform | Tool |
|----------|------|
| Facebook | https://developers.facebook.com/tools/debug/ |
| LinkedIn | https://www.linkedin.com/post-inspector/ |
| Twitter/X | https://cards-dev.twitter.com/validator |
| General | https://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.

Related Skills

socialclaw

5
from FrancoStino/opencode-skills-collection

Agent-first social media publishing skill — schedule and publish posts across 13 platforms (X, LinkedIn, Instagram, Facebook Pages, TikTok, Discord, Telegram, YouTube, Reddit, WordPress, Pinterest) via a single workspace API key.

social-proof-architect

5
from FrancoStino/opencode-skills-collection

One sentence - what this skill does and when to invoke it

social-post-writer-seo

5
from FrancoStino/opencode-skills-collection

Social Media Strategist and Content Writer. Creates clear, engaging social media posts for Instagram, LinkedIn, and Facebook.

social-orchestrator

5
from FrancoStino/opencode-skills-collection

Orquestrador unificado de canais sociais — coordena Instagram, Telegram e WhatsApp em um unico fluxo de trabalho. Publicacao cross-channel, metricas unificadas, reutilizacao de conteudo por formato, agendamento sincronizado e gestao centralizada de campanhas em todos os canais simultaneamente.

social-content

5
from FrancoStino/opencode-skills-collection

You are an expert social media strategist with direct access to a scheduling platform that publishes to all major social networks. Your goal is to help create engaging content that builds audience, drives engagement, and supports business goals.

security-scanning-security-hardening

5
from FrancoStino/opencode-skills-collection

Coordinate multi-layer security scanning and hardening across application, infrastructure, and compliance controls.

fixing-metadata

5
from FrancoStino/opencode-skills-collection

Audit and fix HTML metadata including page titles, meta descriptions, canonical URLs, Open Graph tags, Twitter cards, favicons, JSON-LD structured data, and robots directives. Use when adding or reviewing SEO and social metadata.

container-security-hardening

5
from FrancoStino/opencode-skills-collection

Harden Docker/container images and runtime deployments with secure base images, non-root users, CVE scanning, SBOM/signing, seccomp/AppArmor, and Kubernetes pod security controls. Use for Dockerfile security reviews, container CVEs, image scanning, distroless images, or production hardening.

akf-trust-metadata

5
from FrancoStino/opencode-skills-collection

The AI native file format. EXIF for AI — stamps every file with trust scores, source provenance, and compliance metadata. Embeds into 20+ formats (DOCX, PDF, images, code). EU AI Act, SOX, HIPAA auditing.

zustand-store-ts

5
from FrancoStino/opencode-skills-collection

Create Zustand stores following established patterns with proper TypeScript types and middleware.

zoom-automation

5
from FrancoStino/opencode-skills-collection

Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.

zoho-crm-automation

5
from FrancoStino/opencode-skills-collection

Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.