OG Images for Portfolio Sites: Stand Out When Your Work Gets Shared

How to design and implement OG images for developer and designer portfolios — unique project previews, case study cards, and social-ready work samples.

Why portfolio OG images matter

When a recruiter, client, or collaborator shares your portfolio link in a Slack channel, Discord server, or LinkedIn message — what do they see? If your OG image is missing, broken, or a generic screenshot, you're losing the first impression before anyone even clicks.

A well-designed portfolio OG image is essentially a mini cover letter: it should communicate your role, style, and caliber of work in one glance at 1200×630 pixels.

OG image strategy by page type

Homepage / root URL

Your homepage OG image is the most shared. It should include your name, title (e.g., "Frontend Engineer" or "Product Designer"), and a visual that represents your work quality. Keep it minimal and professional.

Individual project / case study pages

Each project page should have a unique OG image. Use a screenshot or mockup of the project with the project name overlaid. This way, when someone shares a specific project, the preview immediately shows what it is.

Writing / blog section

For portfolio blogs or writing samples, generate OG images dynamically from the post title — branded with your name and domain.

Static OG image implementation (Next.js)

// app/layout.tsx (site-wide default)
import type { Metadata } from "next";

export const metadata: Metadata = {
  metadataBase: new URL("https://yourname.dev"),
  title: {
    default: "Jane Smith — Frontend Engineer",
    template: "%s | Jane Smith",
  },
  description: "I build accessible, high-performance React applications.",
  openGraph: {
    type: "website",
    siteName: "Jane Smith Portfolio",
    images: [
      {
        url: "/og/homepage.png",  // static 1200×630 image
        width: 1200,
        height: 630,
        alt: "Jane Smith — Frontend Engineer",
      },
    ],
  },
  twitter: {
    card: "summary_large_image",
    creator: "@janesmith",
  },
};

Dynamic project OG images (Next.js edge)

For project pages, generate OG images on-the-fly so each project has a unique preview:

// app/work/[slug]/opengraph-image.tsx
import { ImageResponse } from "next/og";
import { getProject } from "@/lib/projects";

export const size = { width: 1200, height: 630 };
export const contentType = "image/png";

export default async function OgImage({
  params,
}: {
  params: { slug: string };
}) {
  const project = getProject(params.slug);
  
  return new ImageResponse(
    (
      <div
        style={{
          display: "flex",
          background: "#0a0a0a",
          width: "100%",
          height: "100%",
          position: "relative",
          overflow: "hidden",
        }}
      >
        {/* Project screenshot on right */}
        {project.screenshot && (
          <img
            src={project.screenshot}
            style={{
              position: "absolute",
              right: -40,
              top: -20,
              width: "60%",
              height: "120%",
              objectFit: "cover",
              opacity: 0.3,
              transform: "rotate(3deg)",
            }}
            alt=""
          />
        )}
        
        {/* Content on left */}
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",
            padding: "60px",
            zIndex: 1,
            maxWidth: "60%",
          }}
        >
          {/* Category tag */}
          <div
            style={{
              fontSize: 18,
              color: "#8b5cf6",
              fontWeight: 600,
              marginBottom: 16,
              textTransform: "uppercase",
              letterSpacing: "0.1em",
            }}
          >
            {project.category}
          </div>
          
          {/* Project name */}
          <div
            style={{
              fontSize: 56,
              fontWeight: 900,
              color: "#ffffff",
              lineHeight: 1.1,
            }}
          >
            {project.title}
          </div>
          
          {/* Short description */}
          <div
            style={{
              fontSize: 22,
              color: "#a1a1aa",
              marginTop: 20,
              lineHeight: 1.4,
            }}
          >
            {project.description}
          </div>
          
          {/* Name attribution */}
          <div
            style={{
              fontSize: 18,
              color: "#52525b",
              marginTop: 32,
            }}
          >
            yourname.dev
          </div>
        </div>
      </div>
    ),
    size
  );
}

Portfolio OG design principles

  • Show your work visually: Include a screenshot or mockup — portfolios are visual by nature
  • Name + title always visible: Recruiters share links in notes/emails — make sure they always know whose work this is
  • Consistent color system: Use your portfolio's primary color so previews look branded, not generic
  • Dark background works well: Dark OG images stand out in social feeds dominated by white backgrounds
  • Font hierarchy: Large project title, smaller description, smallest attribution — maintain visual hierarchy even at thumbnail size
  • No tiny text: If it can't be read at 300px wide, cut it

Static vs dynamic: which approach to use

ApproachBest forTrade-off
Static PNG filesSmall portfolios (<10 projects)Manual effort per page
opengraph-image.tsx per routeNext.js apps with many projectsRequires edge runtime
/api/og?title=... routeBlog posts and text-heavy pagesLess control per page
Figma export per projectUnique branded project cardsMost time-consuming

Check your portfolio's social previews

Paste your portfolio URL into OGFixer to see exactly how it looks when shared on Twitter, LinkedIn, Discord, and Slack — before a recruiter does.

Check your portfolio OG free →