How to Generate GitHub-Style Dynamic OG:Images with Flyyer

Flyyer lets you create GitHub-style social media link previews with dynamic Open Graph (OG) images using React, TailwindCSS, and URL variables.

By Patricio Lopez Juri

Why Do GitHub’s Link Previews Stand Out?

GitHub generates dynamic cards for every repository link. These previews:

  • Include the repo name, description, and avatar
  • Show real-time stats (stars, forks, etc.)
  • Look clean and consistent across platforms

Flyyer allows you to replicate this functionality—without building a custom image service.

📌 Note: GitHub uses its own infrastructure. This example is not affiliated with GitHub.

What Will You Build?

You’ll create a Flyyer template to dynamically render repository previews like GitHub’s cards.

Preview formats supported:

FormatDimensions
Thumbnail400×400 px
Banner1200×630 px (OG)
Square1080×1080 px
Story1080×1920 px

🎯 Live Demo:
 Try editing this preview URL

How to Get Started

Use the create-flyyer-app CLI to scaffold a new project.

bash

CopyEdit

# Using npm
npm init flyyer-app@latest github-cards

# Using Yarn
yarn create flyyer-app github-cards

📦 Choose: react-typescript-tailwind
 This starter uses React, TypeScript, and Tailwind—just like GitHub’s frontend stack.

Project Setup

bash

CopyEdit

cd github-cards
npm install
npm start

This opens Flyyer Studio at useflyyer.github.io/studio/.

How to Build the Template

Edit the template:

bash

CopyEdit

mv templates/article.tsx templates/repository.tsx

Open repository.tsx and structure it with:

  • Repo name
  • Avatar image
  • Description
  • Contributor stats

Flyyer reads dynamic content from the querystring in the URL.

🔧 Tailwind Tweak

Update styles/tailwind.css to set a larger base font size:

css

CopyEdit

html {
  font-size: 36px;
}

This improves sizing in image-based previews.

Example Code: GitHub Repository Template

tsx

CopyEdit

export default function RepositoryTemplate(props: TemplateProps) {
  const {width, height, variables} = props;
  const [owner, repo] = (variables.title || ”).split(‘/’);

  const stats = [
    {Icon: VscOrganization, title: ‘Contributors’, count: variables.contributors},
    {Icon: VscIssues, title: ‘Issues’, count: variables.issues},
    {Icon: VscStarEmpty, title: ‘Stars’, count: variables.stars},
    {Icon: VscRepoForked, title: ‘Forks’, count: variables.forks}
  ];

  return (
    <Layer className=”bg-white px-7 pt-10 pb-8 grid grid-cols-12 grid-rows-12 gap-x-5 text-gray-500″>
      <header className=”col-span-9 row-span-10″>
        <h1 className=”text-3xl tracking-normal text-gray-800″>
          <span>{owner}</span>{owner && repo && <span>/</span>}
          <span className=”font-bold”>{repo}</span>
        </h1>
        <p className=”pt-3 text-base font-light leading-snug”>{variables.description}</p>
      </header>
      <div className=”col-span-3 row-span-10″>
        {variables.avatar && (
          <img src={variables.avatar} className=”rounded-md w-full object-contain” />
        )}
      </div>
      <dl className=”col-span-12 row-span-2 flex flex-wrap space-x-6″>
        {stats.map(({title, count, Icon}, i) => (
          <div key={i} className=”flex space-x-1″>
            <Icon className=”w-4 h-4″ />
            <div>
              <dt className=”text-sm text-gray-700″>{Number.isFinite(count) ? count : ‘-‘}</dt>
              <dd className=”text-xs text-gray-400″>{title}</dd>
            </div>
          </div>
        ))}
      </dl>
    </Layer>
  );
}

📌 Use the Flyyer Studio Variables UI to test your image output.

How to Add Responsive Breakpoints in Tailwind

Flyyer templates have unique dimensions. Extend Tailwind breakpoints in tailwind.config.js:

js

CopyEdit

screens: {
  thumb: {raw: ‘(min-height: 400px)’},
  banner: {raw: ‘(min-height: 630px)’},
  sq: {raw: ‘(min-height: 1080px)’},
  story: {raw: ‘(min-height: 1920px)’},
  …defaultTheme.screens
}

✅ Enables conditional styles for image sizes like story:text-4xl or sq:mt-4.

How to Deploy Your Template

bash

CopyEdit

NODE_ENV=production npm run-script build
npm run-script deploy

⚠️ Missing key?

  • Visit flyyer.com/dashboard/_/settings
  • Set your FLYYER_KEY in a .env file:

bash

CopyEdit

# .env
FLYYER_KEY=your-key-here

🔗 Deploy URLs Example:

bash

CopyEdit

https://cdn.flyyer.io/v2/render/flyyer/github-cards/repository.jpeg?title=Thanks+for+using+Flyyer

How to Integrate With Next.js

Flyyer works by injecting dynamic URLs into Open Graph meta-tags.

tsx

CopyEdit

import Head from “next/head”
import { FlyyerRender } from “@flyyer/flyyer”

export function MyHead({ title, description, avatar, contributors, issues, forks, stars }) {
  const flyyer = new FlyyerRender({
    tenant: “flyyer”,
    deck: “github-cards”,
    template: “repository”,
    variables: { title, description, avatar, contributors, issues, forks, stars }
  });

  return (
    <Head>
      <meta property=”og:image” content={flyyer.href()} />
      <meta name=”twitter:image” content={flyyer.href()} />
      <meta name=”twitter:card” content=”summary_large_image” />
    </Head>
  );
}

What’s Next?

In the next post, we’ll cover:

  • How to declare variables with @flyyer/variables
  • How to enable the Live Template UI on the Flyyer Dashboard

Helpful Links

  • 📖 Flyyer Docs
  • 🧠 Flyyer URL Formatters
  • 🐦 Follow us on Twitter
  • 💬 Join our Discord

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *