Dynamic OG Images for React

Add beautiful, dynamic social share images to your React application. Works with Create React App, Vite, Remix, and any React setup.

Get API Key → Full Docs

Understanding OG Images in React SPAs

⚠️ Important: Client-side React apps (SPAs) cannot set meta tags for social media crawlers because they execute JavaScript. Social crawlers like Twitter and Facebook don't run JavaScript — they only see your initial HTML.

For dynamic OG images in React, you need one of these approaches:

Option 1: React with SSR Framework (Recommended)

The easiest approach is using a React framework with SSR:

Remix Example

app/routes/blog.$slug.tsx
import { json, MetaFunction, LoaderFunction } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';

export const loader: LoaderFunction = async ({ params }) => {
  const post = await getPost(params.slug);
  
  const ogImage = `https://ogimageapi.io/api/generate?` +
    new URLSearchParams({
      title: post.title,
      subtitle: post.author,
      theme: 'dark'
    });
  
  return json({ post, ogImage });
};

export const meta: MetaFunction = ({ data }) => {
  const { post, ogImage } = data;
  
  return [
    { title: post.title },
    { name: 'description', content: post.excerpt },
    { property: 'og:title', content: post.title },
    { property: 'og:description', content: post.excerpt },
    { property: 'og:image', content: ogImage },
    { name: 'twitter:card', content: 'summary_large_image' },
    { name: 'twitter:image', content: ogImage }
  ];
};

export default function BlogPost() {
  const { post } = useLoaderData<typeof loader>();
  
  return (
    <article>
      <h1>{post.title}</h1>
      {/* content */}
    </article>
  );
}

Option 2: React-Helmet for SPAs with Pre-rendering

If you're using a pre-rendering service, use React-Helmet to set meta tags:

src/components/SEO.tsx
import { Helmet } from 'react-helmet-async';

interface SEOProps {
  title: string;
  description: string;
  author?: string;
}

export function SEO({ title, description, author }: SEOProps) {
  const ogImage = `https://ogimageapi.io/api/generate?` +
    new URLSearchParams({
      title,
      subtitle: author || '',
      theme: 'dark'
    });
  
  return (
    <Helmet>
      <title>{title}</title>
      <meta name="description" content={description} />
      
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={ogImage} />
      <meta property="og:type" content="article" />
      
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={title} />
      <meta name="twitter:description" content={description} />
      <meta name="twitter:image" content={ogImage} />
    </Helmet>
  );
}

// Usage in a page component
function BlogPost({ post }) {
  return (
    <>
      <SEO 
        title={post.title} 
        description={post.excerpt}
        author={post.author}
      />
      <article>
        <h1>{post.title}</h1>
      </article>
    </>
  );
}

Option 3: Vite SSR

For Vite projects, enable SSR for OG image support:

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  ssr: {
    noExternal: ['react-helmet-async']
  }
});

Build-Time Image Generation

For static sites, generate OG images at build time:

scripts/generate-og-images.ts
import fs from 'fs';
import path from 'path';

async function generateOGImages() {
  const posts = await getAllPosts();
  
  for (const post of posts) {
    const response = await fetch('https://ogimageapi.io/api/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.OG_IMAGE_API_KEY
      },
      body: JSON.stringify({
        title: post.title,
        subtitle: post.author,
        theme: 'dark'
      })
    });
    
    const buffer = Buffer.from(await response.arrayBuffer());
    const outputPath = path.join('public', 'og', `${post.slug}.png`);
    
    fs.writeFileSync(outputPath, buffer);
    console.log(`Generated: ${outputPath}`);
  }
}

generateOGImages();

Ready to Add OG Images to React?

Get started with 25 free images per month.

Get Your API Key →

More Integration Guides