Social Preview Caching | Blue Frog Docs

Social Preview Caching

Fix stale social media previews after content updates

Social Preview Caching

What This Means

Social platforms cache your Open Graph and Twitter Card metadata to improve performance. When you update your content, old previews may persist for hours or days. This causes:

  • Old images showing after you've updated them
  • Previous titles/descriptions appearing in shares
  • Broken images after URL changes
  • Inconsistent previews across shares

Cache Duration by Platform

Platform Cache Duration Manual Refresh
Facebook Up to 30 days Sharing Debugger
Twitter/X ~7 days Card Validator
LinkedIn Up to 7 days Post Inspector
Slack Until webhook Re-post link
Discord ~24 hours Varies by server
WhatsApp ~7 days No manual refresh

How to Diagnose

1. Check What's Cached

Facebook:

  1. Go to Sharing Debugger
  2. Enter URL and click "Debug"
  3. Compare "Link Preview" with your current OG tags
  4. Note "Time Scraped" to see cache age

Twitter:

  1. Visit Card Validator
  2. Enter URL
  3. Compare preview with actual meta tags

LinkedIn:

  1. Go to Post Inspector
  2. Enter URL
  3. Review cached metadata

2. Compare Live vs Cached

// Check what platforms will scrape
fetch('https://example.com/page')
  .then(res => res.text())
  .then(html => {
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');
    console.log('Current OG Title:',
      doc.querySelector('meta[property="og:title"]')?.content);
  });

General Fixes

Force Cache Refresh by Platform

Facebook:

# Using Graph API (programmatic)
curl -X POST \
  "https://graph.facebook.com/?id=https://example.com/page&scrape=true&access_token=YOUR_TOKEN"

Or manually:

  1. Go to Sharing Debugger
  2. Enter your URL
  3. Click "Scrape Again"
  4. Repeat if necessary (sometimes needs 2-3 scrapes)

Twitter:

  1. Open Card Validator
  2. Enter URL
  3. Click "Preview Card"
  4. Cache typically updates within hours

LinkedIn:

  1. Go to Post Inspector
  2. Enter URL
  3. Click "Inspect"
  4. The scrape refreshes the cache

Slack:

  • Unfurl cache clears when URL pattern changes
  • Add query parameter to force refresh: ?v=2
  • Or wait for automatic expiry (~30 minutes for unfurls)

Cache Busting Techniques

1. Query Parameter Versioning:

<!-- Add version parameter when content changes -->
<meta property="og:image" content="https://example.com/image.jpg?v=20250115">

2. Unique Filenames:

<!-- Use content-hashed filenames -->
<meta property="og:image" content="https://example.com/og-image-abc123.jpg">

3. CDN Cache Invalidation:

# Cloudflare
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -d '{"files":["https://example.com/og-image.jpg"]}'

# AWS CloudFront
aws cloudfront create-invalidation --distribution-id XXXXXX --paths "/og-image.jpg"

Automated Cache Refresh

On Content Update (WordPress):

// Refresh Facebook cache when post is updated
add_action('save_post', 'refresh_facebook_cache', 10, 3);
function refresh_facebook_cache($post_id, $post, $update) {
    if (!$update) return;

    $url = get_permalink($post_id);
    $access_token = get_option('facebook_access_token');

    wp_remote_post("https://graph.facebook.com/?id=" . urlencode($url) .
      "&scrape=true&access_token=" . $access_token);
}

Using Webhooks:

// Trigger cache refresh on deploy
async function refreshSocialCaches(pageUrl) {
  // Facebook
  await fetch(`https://graph.facebook.com/?id=${encodeURIComponent(pageUrl)}&scrape=true`);

  // LinkedIn (requires authentication)
  // Note: LinkedIn doesn't have a public API for this

  console.log(`Cache refresh triggered for: ${pageUrl}`);
}

Prevent Caching Issues

1. Use absolute, stable URLs:

<!-- Good: Absolute, versioned URL -->
<meta property="og:image" content="https://cdn.example.com/v2/og-image.jpg">

<!-- Bad: Relative or dynamic URL -->
<meta property="og:image" content="/images/og-image.jpg">

2. Set appropriate cache headers:

# Nginx: Allow crawlers to get fresh content
location /og-images/ {
    add_header Cache-Control "public, max-age=86400";
    add_header Vary "User-Agent";
}

3. Implement og:updated_time:

<meta property="og:updated_time" content="2025-01-15T10:30:00Z">

Platform-Specific Guides

Platform Guide
Shopify Shopify Cache Refresh
WordPress WordPress Social Cache

Verification

  1. Use platform debuggers to verify fresh content
  2. Share in private group to test preview
  3. Check from incognito/different account
  4. Monitor cache refresh success in logs

Common Mistakes

Mistake Fix
Not waiting for scrape to complete Click "Scrape Again" multiple times
Old image URL still resolving Update filename, not just file
CDN serving stale content Purge CDN cache before social refresh
Using JavaScript-only OG tags Ensure SSR for social crawlers

Further Reading

// SYS.FOOTER