Generate Open Graph images for your React + Vite app using React components.
- 🎨 Use React components to design OG images
- âš¡ Fast image generation powered by @vercel/og
npm install vite-plugin-react-og-image
# or
pnpm add vite-plugin-react-og-image
# or
yarn add vite-plugin-react-og-image
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import reactOgImage from "vite-plugin-react-og-image";
export default defineConfig({
plugins: [
react(),
reactOgImage({
// Specify the host for production builds
host: "https://example.com",
}),
],
});
// src/og-image.tsx (or .jsx, .ts, .js)
export default function OgImage() {
return (
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#1a1a1a",
color: "white",
fontFamily: "Inter, system-ui, sans-serif",
fontSize: 72,
fontWeight: 600,
textAlign: "center",
padding: 40,
}}
>
<div>Your Amazing App</div>
<div style={{ fontSize: 36, opacity: 0.8, marginTop: 20 }}>
This is a dynamic OG image!
</div>
</div>
);
}
The plugin automatically inserts the necessary og:image
meta tag in your HTML. You can add other Open Graph meta tags as needed:
<!-- index.html - Add these manually if needed -->
<meta property="og:title" content="Your Page Title" />
<meta property="og:description" content="Your page description" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://example.com/" />
<!-- Twitter Card meta tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Your Page Title" />
<meta name="twitter:description" content="Your page description" />
- Access
/src/og-image
to preview your OG image (extension will be auto-detected) - The plugin intercepts requests and generates PNG images on-the-fly
- Automatically generates static PNG images during build
- Updates HTML meta tags with hashed filenames
- Images are optimized and placed in the
dist/assets
directory
interface OgImagePluginOptions {
/**
* The host URL for production builds
* Used to generate absolute URLs in meta tags
*/
host: string;
/**
* OG image component path
* Extension is optional - will try .tsx, .jsx, .ts, .js in that order
* @default './src/og-image'
*/
componentPath?: string;
/**
* Image response options (from @vercel/og)
* See: https://vercel.com/docs/functions/og-image-generation
* Note: ResponseInit properties (status, headers, etc.) are not supported
*/
imageResponseOptions?: {
width?: number; // Default: 1200
height?: number; // Default: 630
emoji?: "twemoji" | "blobmoji" | "noto" | "openmoji";
fonts?: Array<{
name: string;
data: ArrayBuffer;
weight?: number;
style?: "normal" | "italic";
}>;
debug?: boolean;
// ... other @vercel/og options
};
}
Use @fontsource packages for easy font integration:
pnpm add @fontsource/geist @fontsource/noto-serif-jp
import { readFile } from "fs/promises";
export default defineConfig({
plugins: [
react(),
reactOgImage({
host: "https://example.com",
imageResponseOptions: {
fonts: [
{
name: "Geist",
data: await readFile(
"./node_modules/@fontsource/geist/files/geist-latin-700-normal.woff"
),
weight: 700,
},
{
name: "Noto Serif JP",
data: await readFile(
"./node_modules/@fontsource/noto-serif-jp/files/noto-serif-jp-japanese-400-normal.woff"
),
weight: 400,
},
],
},
}),
],
});
Check out the example directory for a complete working example.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © sunya9