Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
dicklesworthstone avatar

Creating Share Images

  • 12 installs
  • 185 repo stars
  • Updated August 4, 2026
  • dicklesworthstone/meta_skill

Generates dynamic OpenGraph and Twitter share images in Next.js using next/og ImageResponse with gradients, SVG icons, and correct dimensions.

About

Shows how to build social preview cards with next/og ImageResponse, covering file naming, Satori layout rules, and design patterns. A developer uses it to add OG and Twitter share images to a Next.js app.

  • opengraph-image.tsx (1200x630) and twitter-image.tsx (1200x600) conventions
  • Satori rules: display:flex everywhere, inline styles, gradient text tricks

Creating Share Images by the numbers

  • 12 all-time installs (skills.sh)
  • Ranked #1,643 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dicklesworthstone/meta_skill --skill creating-share-images

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs12
repo stars185
Last updatedAugust 4, 2026
Repositorydicklesworthstone/meta_skill

What it does

Generates dynamic OpenGraph and Twitter share images in Next.js using next/og ImageResponse with gradients, SVG icons, and correct dimensions.

Files

SKILL.mdMarkdownGitHub ↗

Creating Share Images for Next.js

Generate dynamic OpenGraph (1200x630) and Twitter (1200x600) images using next/og ImageResponse.

Quick Start

Create app/opengraph-image.tsx:

import { ImageResponse } from "next/og";

export const runtime = "edge";
export const alt = "Page Title - Site Description";
export const size = { width: 1200, height: 630 };
export const contentType = "image/png";

export default async function Image() {
  return new ImageResponse(
    (
      <div style={{
        height: "100%",
        width: "100%",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        background: "linear-gradient(145deg, #0a0a12 0%, #0f1218 50%, #0a0a12 100%)",
        fontFamily: "system-ui, -apple-system, sans-serif",
      }}>
        <h1 style={{ fontSize: 64, color: "#ffffff", margin: 0 }}>
          Page Title
        </h1>
      </div>
    ),
    { ...size }
  );
}

File Naming Convention

FilePurposeDimensions
opengraph-image.tsxFacebook, LinkedIn, iMessage1200×630
twitter-image.tsxTwitter/X cards1200×600

Place in route directory (e.g., app/about/opengraph-image.tsx for /about).

Design Patterns

Gradient Backgrounds

background: "linear-gradient(145deg, #0a0a12 0%, #0f1218 35%, #121620 65%, #0a0a12 100%)"

Glowing Orbs (Depth Effect)

<div style={{
  position: "absolute",
  top: -150,
  left: -100,
  width: 500,
  height: 500,
  borderRadius: "50%",
  background: "radial-gradient(circle, rgba(34,211,238,0.15) 0%, transparent 60%)",
  display: "flex",
}} />

Gradient Text

<h1 style={{
  fontSize: 62,
  fontWeight: 800,
  background: "linear-gradient(135deg, #ffffff 0%, #e2e8f0 50%, #94a3b8 100%)",
  backgroundClip: "text",
  color: "transparent",
  display: "flex",
}}>Title</h1>

SVG Icons with Gradients

<svg width="200" height="200" viewBox="0 0 100 100" fill="none"
  style={{ filter: "drop-shadow(0 0 24px rgba(34,211,238,0.35))" }}>
  <defs>
    <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" stopColor="#22d3ee" />
      <stop offset="100%" stopColor="#a855f7" />
    </linearGradient>
  </defs>
  <circle cx="50" cy="50" r="45" stroke="url(#grad)" strokeWidth="2" fill="none" />
</svg>

Critical Rules

1. Always use `display: "flex"` on every element (Satori requirement) 2. No `gap` on containers without `display: "flex"` 3. Use inline styles only - no CSS classes or external stylesheets 4. All text must be wrapped in elements with explicit styling 5. SVG must use `viewBox` and explicit dimensions 6. Filter property only on SVG root - not on child elements

Color Palette by Section Type

SectionPrimarySecondaryAccent
Homepage#3b82f6 blue#8b5cf6 purple#06b6d4 cyan
About#10b981 emerald#14b8a6 teal#22c55e green
Projects#f97316 orange#f59e0b amber#f43f5e rose
Writing#ec4899 pink#f472b6 rose#6366f1 indigo
Tools/TLDR#22d3ee cyan#a855f7 purple#f472b6 pink

Badge/Tag Pattern

<div style={{
  display: "flex",
  padding: "7px 14px",
  borderRadius: 8,
  background: "rgba(34,211,238,0.15)",
  border: "1px solid rgba(34,211,238,0.3)",
}}>
  <span style={{ color: "#22d3ee", fontWeight: 600, display: "flex" }}>
    Label
  </span>
</div>

Bottom Gradient Accent

<div style={{
  position: "absolute",
  bottom: 0,
  left: 0,
  right: 0,
  height: 4,
  background: "linear-gradient(90deg, transparent 0%, #22d3ee 25%, #a855f7 50%, #f472b6 75%, transparent 100%)",
  display: "flex",
}} />

Testing

After creating images, run bun run build (or npm run build) to verify routes register as dynamic:

Route (app)                    Size     First Load JS
├ ƒ /opengraph-image          0 B      0 B
├ ƒ /twitter-image            0 B      0 B

The ƒ indicates dynamic (edge) functions.

Common Issues

IssueSolution
Text not renderingAdd display: "flex" to text wrapper
Layout brokenEnsure all containers have display: "flex"
Colors wrongUse hex colors, not CSS variables
SVG not showingAdd explicit width/height attributes
Gradient text invisibleNeed both backgroundClip: "text" AND color: "transparent"

Extended Patterns

See patterns.md for complete examples including:

  • Flywheel diagrams
  • Document/writing visuals
  • Code window icons
  • Network/connection graphics
  • Journey path visualizations

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.