# Missing social preview image (og:image)

> With no og:image, links to your page show a blank box on Slack, X, and iMessage. Add a 1200×630 preview image so shares look real.

_Category: Search visibility · Detector `seo` · Check `og-image-missing` · Severity: warning_

When your page is shared on Slack, X, LinkedIn, or iMessage, the platform reads `<meta property="og:image">` to draw the preview card. With none, the link renders as a bare, blank box — a preview that says “this looks broken”. AI-built pages almost never generate an OG image because it is an asset plus a head tag, not component code.

## Symptoms

- Shared links show an empty or generic grey preview
- Slack/Discord unfurls have no thumbnail
- Link previews look unfinished next to competitors’ rich cards

## How VibeCheck detects it

The `seo` detector flags this live in the browser and reports it to the widget's Problems list — and to your coding agent over MCP.

- **Issue string:** `Missing social preview image (og:image)`
- **Threshold:** no <meta property="og:image">

## Root causes

- No OG image asset was ever created
- The `<head>` is unmanaged so no `og:*` tags are emitted
- Only `og:title` was set, leaving the image out

## The fix

Add an `og:image` pointing to a 1200×630 PNG or JPG at an absolute URL (crawlers do not resolve relative paths). Include `og:image:width/height` so platforms can lay out the card before the image loads.

### Steps

1. Create a 1200×630 preview image (or generate one per route)
2. Host it at an absolute URL
3. Add `og:image` plus width/height meta tags in `<head>`

```html
<meta property="og:image" content="https://acme.com/og/pricing.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
```

## Framework-specific fixes

### React

Render the `og:image` meta tags in the component (React 19), using an absolute URL.

```tsx
<meta property="og:image" content="https://acme.com/og/pricing.png" />
```

### Next.js

Set images in the metadata `openGraph` object, or generate them dynamically with the built-in `ImageResponse` in an `opengraph-image.tsx` file — Next wires up the tags and dimensions.

```tsx
export const metadata: Metadata = {
  openGraph: {
    images: [{ url: 'https://acme.com/og/pricing.png', width: 1200, height: 630 }],
  },
}
```

[Next.js docs](https://nextjs.org/docs/app/api-reference/functions/generate-metadata#opengraph)

### Vue

Add the `og:image` entries to `useHead`’s meta array with `property` keys.

```ts
useHead({
  meta: [{ property: 'og:image', content: 'https://acme.com/og/pricing.png' }],
})
```

### Svelte

Emit the `og:image` tag inside `<svelte:head>`.

```svelte
<svelte:head>
  <meta property="og:image" content="https://acme.com/og/pricing.png" />
</svelte:head>
```

### Vanilla JS

Add the `og:image` tags to each page’s `<head>` with an absolute URL.

```html
<meta property="og:image" content="https://acme.com/og/pricing.png" />
```

## FAQ

### What size should the `og:image` be?

1200×630 pixels (1.91:1) is the standard that renders well everywhere. Keep it under ~1MB and use PNG or JPG.

### Can I use a relative image URL?

No. Crawlers fetch `og:image` from an absolute URL. A relative path resolves against the crawler, not your site, and fails.

### Why is my new image not showing when I share?

Platforms cache unfurls aggressively. Use the platform’s debugger (e.g. the Facebook Sharing Debugger or X Card Validator) to force a re-scrape.

## Related problems

- [Missing og:title](https://vibecheck.wcgw.fun/fix/missing-og-title.md) — Search visibility
- [Missing og:description](https://vibecheck.wcgw.fun/fix/missing-og-description.md) — Search visibility
- [Missing Twitter/X card](https://vibecheck.wcgw.fun/fix/missing-twitter-card.md) — Search visibility
- [Missing meta description](https://vibecheck.wcgw.fun/fix/missing-meta-description.md) — Search visibility

---

Fix guide from VibeCheck — https://vibecheck.wcgw.fun/fix/missing-og-image. Full site index for LLMs: https://vibecheck.wcgw.fun/llms.txt
