Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set the og:image metadata property to an absolute, publicly reachable image URL:

<meta property="og:image" content="https://example.com/images/article-share.jpg" />

That tag tells social networks and messaging apps which image to use for a shared URL. For reliable route-specific previews, the tag must be present in the HTML response delivered to the crawler—not only added later by browser-side JavaScript. In Next.js, use the Metadata API or an opengraph-image file; in another React stack, use server rendering or prerendering that emits the tag before a crawler reads the page.

What an Open Graph image tag does

Open Graph metadata describes a URL when it is shared. The image property is normally accompanied by title, description, URL and type:

<meta property="og:title" content="Example article" />
<meta property="og:description" content="A useful page description" />
<meta property="og:url" content="https://example.com/articles/example" />
<meta property="og:type" content="article" />
<meta property="og:image" content="https://example.com/images/example-share.jpg" />

The image URL should be absolute and reachable without an authenticated browser session. Keep the image at a stable HTTPS address, allow the crawler to fetch it, and make the content match the page being shared. A browser’s Elements panel can show a correct tag even when a preview bot never received it, because the browser may have executed React while the bot only inspected the original response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Plain React: add the tag to the document head

Static metadata

In a React application whose server or prerenderer supplies the document head, render the metadata with React:

export default function ArticleHead() {
  return (
    <>
      <meta property="og:title" content="Example article" />
      <meta property="og:description" content="A useful page description" />
      <meta property="og:url" content="https://example.com/articles/example" />
      <meta property="og:type" content="article" />
      <meta
        property="og:image"
        content="https://example.com/images/example-share.jpg"
      />
    </>
  )
}

React’s <meta> component is placed in the document head regardless of where the component appears in the React tree. This makes metadata easy to compose. It does not, by itself, guarantee that an external crawler executes your client application or waits for a client-side update.

Route-specific values

Build the image URL from the same route data that renders the page, and render one value for each URL:

function ArticleMeta({ article }) {
  const origin = 'https://example.com'
  const pageUrl = `${origin}/articles/${article.slug}`
  const imageUrl = `${origin}/images/articles/${article.slug}-share.jpg`

  return (
    <>
      <meta property="og:title" content={article.title} />
      <meta property="og:description" content={article.description} />
      <meta property="og:url" content={pageUrl} />
      <meta property="og:type" content="article" />
      <meta property="og:image" content={imageUrl} />
    </>
  )
}

For a client-rendered single-page app, configure your host to server-render or prerender each public route when previews matter. Otherwise, put equivalent tags in the initial HTML template as a fallback, understanding that a single default image cannot represent every route.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Next.js App Router: use the Metadata API

Static metadata

Export a Metadata object from a Server Component such as app/layout.tsx or a route page:

import type { Metadata } from 'next'

export const metadata: Metadata = {
  openGraph: {
    title: 'Example page',
    description: 'A useful description',
    url: 'https://example.com/example',
    images: [{
      url: 'https://example.com/images/example-share.jpg',
      width: 1200,
      height: 630,
      alt: 'Description of the image',
    }],
  },
}

export default function Page() {
  return <main>Example page</main>
}

openGraph.images accepts a URL or an object with an image URL and optional dimensions and alternative text. Put a site origin in metadataBase in a root layout when you want relative metadata URLs resolved against that origin; an absolute URL takes precedence.

import type { Metadata } from 'next'

export const metadata: Metadata = {
  metadataBase: new URL('https://example.com'),
  openGraph: {
    images: ['/images/default-share.jpg'],
  },
}

Dynamic routes with generateMetadata

Load the page record and return metadata tied to its slug:

import type { Metadata } from 'next'

type Props = { params: Promise<{ slug: string }> }

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params
  const article = await getArticle(slug)
  const origin = 'https://example.com'

  return {
    title: article.title,
    description: article.description,
    openGraph: {
      title: article.title,
      description: article.description,
      url: `${origin}/articles/${slug}`,
      type: 'article',
      images: [{
        url: `${origin}/images/articles/${slug}-share.jpg`,
        width: 1200,
        height: 630,
        alt: article.imageAlt,
      }],
    },
  }
}

Metadata and generateMetadata are supported in Server Components. Be deliberate with inheritance: when a child route defines its own openGraph object, it replaces the parent’s entire Open Graph object. Repeat or spread shared fields intentionally so a child does not accidentally discard the site description, URL or other defaults.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Next.js file convention: opengraph-image

Static image beside a route

Place opengraph-image.jpg, .jpeg, .png or .gif in the relevant App Router segment. Next.js emits the Open Graph image metadata automatically, and a deeper route image takes precedence over one in a higher-level segment. Add opengraph-image.alt.txt beside a file image when you want descriptive alternative text.

Generated image route

Create opengraph-image.tsx when the image must be generated from route data:

import { ImageResponse } from 'next/og'

export const alt = 'Article share image'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'

export default async function Image() {
  return new ImageResponse(
    <div style={{
      width: '100%', height: '100%', display: 'flex',
      alignItems: 'center', justifyContent: 'center',
      background: 'white', fontSize: 64,
    }}>
      Example article
    </div>,
    size,
  )
}

Generated images can use route parameters. They are statically optimized by default unless they depend on request-time APIs or uncached data. Current Next.js documentation lists an 8 MB maximum for an opengraph-image file and a 5 MB maximum for a twitter-image file. Those are Next.js build constraints, not universal limits imposed by every social platform.

Choosing between the two Next.js approaches

Need Best fit Why
One known image URL or data-driven metadata Metadata API Explicitly set URL, dimensions and alt text; generateMetadata can load route data.
A file naturally co-located with a route opengraph-image file Next.js emits tags automatically and deeper segments override parent images.
Image text or layout generated from content opengraph-image.tsx Return a generated image and derive it from route parameters.

Make crawlers receive the metadata

A preview crawler requests the shared URL and reads metadata from the response. Next.js identifies facebookexternalhit as an HTML-limited bot that cannot execute JavaScript, and keeps streamed metadata in the head for such bots. The practical rule for any React stack is to deliver route-specific tags through server rendering, prerendering or an equivalent HTML-generation step.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Use one canonical, absolute page URL in og:url.
  • Return one intended og:image value for the route, rather than several competing defaults.
  • Make the image URL publicly fetchable and check redirects, access rules and certificate errors.
  • Provide useful image alt text in Next.js metadata or the file-convention sidecar file.

Debug a missing or stale preview

  1. Inspect the response HTML. Request the exact public URL with a tool such as curl or view the server response in your browser’s network panel. Search the returned HTML for property="og:image" and verify the route-specific value. Do not rely only on the post-hydration Elements panel.
  2. Fetch the image URL directly. Confirm it resolves to the intended image, does not require login, and is not blocked by redirects or server access controls.
  3. Check metadata inheritance. In Next.js, a child openGraph object can replace the parent object. Verify that a layout default has not replaced the child image, or that a child has not removed shared fields.
  4. Check the platform’s debugger. Preview tools differ by platform and may cache fetched HTML and images. Use the platform’s own refresh or scrape option when available, then verify the new response again.

Common symptoms and fixes

Symptom Likely cause Fix
Browser shows the tag, preview does not Tag was added only after client JavaScript ran. Emit it in initial server HTML or prerender the route.
Every article uses the same image Only a root layout or HTML template defines og:image. Return route-specific metadata with generateMetadata or a route image file.
No image appears Image URL is relative, blocked, redirected unexpectedly or inaccessible. Use an absolute HTTPS URL and test it without cookies or authentication.
Old image persists The preview service cached an earlier fetch. Use its debugging or refresh tool; confirm the current response before waiting for cache expiry.
Next.js child metadata loses title or description Child openGraph replaced the parent object. Repeat or spread the shared Open Graph fields in the child metadata.

Performance, reliability and image choices

Prefer a stable, cacheable image URL and generate images ahead of time when content does not change per request. Keep generated layouts deterministic: a crawler may fetch at a different time or from a different region than a browser. Route data used by generateMetadata should be available under the same caching and failure conditions as the page itself; otherwise a metadata request can fall back to a default or fail with the route.

Declare dimensions when using the Metadata API so consuming services have useful sizing information, and keep important text away from the edges because preview crops vary. Use a file format supported by your deployment and verify the final response’s content type. The documented Next.js file-size limits apply during the build; they do not guarantee acceptance by a particular social network.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup: ScreenshotNeo

If you need to verify what a public React route actually looks like, ScreenshotNeo can capture it through one API request. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before the capture; each cleanup step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

For a quick capture of a route:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for options such as full-page capture, CSS-selector element capture, device presets, custom viewport and retina scale, PDF output, custom CSS or JavaScript, clicks, wait conditions, blocked resources, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks and bulk capture of up to 100 URLs per call. The same service also accepts HTML/CSS-to-image requests, usage queries and an OpenAPI specification.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and annual billing provides two months free. Create a free ScreenshotNeo account to test a route without setting up browser automation.

Frequently Asked Questions

Should I use name="og:image" instead of property="og:image"?

Use the Open Graph form shown here: <meta property="og:image" content="...">.

Can one image serve every React route?

Yes, but it produces a generic preview. Route-specific metadata or image files are needed when each article, product or profile should have its own image.

Do I need a separate Twitter image tag?

Not for the Open Graph implementation itself. Add platform-specific metadata only when your distribution requirements call for it, and keep the Open Graph image valid independently.

Why does a preview work for the home page but not a nested route?

The nested route may not emit its own initial HTML metadata, may inherit an unintended layout value, or may expose an image URL that the crawler cannot fetch. Inspect that exact route’s response and image URL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.