ScreenshotNeo

BlogHow-to

How to Generate Social Cards from Markdown Content

Turn Markdown frontmatter into social preview images, connect them to page metadata, and choose a build-time or request-time workflow.

By the ScreenshotNeo team4 October 20268 min read

To generate social cards from Markdown content, read each document’s frontmatter, pass its title and other chosen fields into a reusable image template, publish the resulting image at a public URL, and point the page’s Open Graph metadata to that URL. For a static site, generate the image at build time; for content that depends on request-time data, use a server or edge route.

These are two related jobs: rendering the card image and connecting it to the page metadata. A generated PNG that is not referenced in the page’s metadata will not reliably appear as its social preview.

1. Choose the fields and card design

Start with deliberate frontmatter fields, usually a title and perhaps an author, category, or supplied image. Keep site identity in the shared template. Avoid treating the full Markdown body as card text: formatting, links, and code are generally not suitable as-is.

---
title: "How to Generate Social Cards from Markdown Content"
description: "A practical guide to Markdown-driven social preview images."
author: "Example Author"
cardImage: "/social/custom-card.png"
---

Decide how the template handles long titles, missing values, punctuation, and line breaks. Provide sensible defaults for optional fields, and constrain or wrap long text so it stays within the card. Keep user-authored content as text rather than interpreting it as HTML.

2. Choose when to render the image

Approach Good fit Considerations
Build time Markdown is committed before deployment and cards change with the content build. Produces a stable image alongside the site. A content edit requires a rebuild and deployment.
Request time Card values depend on request-time data or uncached content. Requires a compatible server or edge runtime and a plan for caching, failures, and image availability.

Do not assume every framework or hosting target supports the same image runtime or caching behavior. Verify the chosen renderer and deployment documentation before relying on a particular route or regeneration model.

3. Next.js App Router

Next.js supports route-segment opengraph-image and twitter-image conventions. Put a static image in the segment, or generate one with a supported JavaScript or TypeScript file. Next.js recognizes these files and adds corresponding metadata. Its documentation describes generated images as statically optimized by default unless request-time APIs or uncached data change that behavior.

Here is a generated-image route using ImageResponse. Place it at an appropriate route segment as opengraph-image.tsx and adapt the title source to your content model. The example demonstrates a fixed title; for one card per Markdown route, resolve that route’s content and pass its frontmatter title into the template.

import { ImageResponse } from 'next/og'

export const alt = 'Social card for the article'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'

export default function OpenGraphImage() {
  const title = 'Generate social cards from Markdown'

  return new ImageResponse(
    (
      <div
        style={{
          width: '100%',
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'flex-end',
          padding: 64,
          background: '#101827',
          color: 'white',
          fontSize: 64,
          fontWeight: 700,
        }}
      >
        <div style={{ fontSize: 24, marginBottom: 24 }}>Example site</div>
        <div>{title}</div>
      </div>
    ),
    { ...size },
  )
}

Next.js documents 1200 by 630 pixels as the example dimensions and PNG output for ImageResponse. You can export alt, size, and contentType from a metadata image route. Its documented image-file formats include JPG, JPEG, PNG, and GIF. The documentation lists a 5 MB maximum for a Twitter image file and 8 MB for an Open Graph image file; check the current requirements of the platform where you plan to share.

For a committed static image, use the route-segment file convention and keep its URL stable. If a page-specific generated route needs frontmatter from a dynamic route, follow the current Next.js metadata-file documentation for route parameters and runtime behavior.

4. Astro

Astro Markdown files can define YAML or TOML frontmatter with fields such as title, description, and tags. Astro exposes Markdown content and frontmatter through local imports or content collection queries. Content collections can define and validate a shared content shape, with type safety and editor IntelliSense.

A typical implementation has three parts:

  1. Load a Markdown entry or query a content collection.
  2. Pass its frontmatter values to a shared card template.
  3. Render an image during the build or expose an image endpoint using a renderer supported by your deployment target.

Astro’s Markdown and content APIs provide the content side of this workflow; the image-rendering method depends on your renderer and hosting stack. Check those deployment requirements before choosing a build or request-time route.

5. Astro with Cloudflare Browser Run

Cloudflare documents one concrete route-based option: an Astro route renders the card design, Browser Run takes a PNG screenshot, and the image is served to social crawlers. Its example accepts title, image, and author values through query parameters. The documented prerequisites are a Cloudflare account with Browser Run enabled, an Astro site deployed on Cloudflare Workers, and basic familiarity with Astro and Workers.

This is a deployment-specific workflow, not a general requirement for Markdown-driven cards. If you use query parameters, encode their values correctly and avoid putting private or sensitive content in a public image URL.

6. Publish the image and page metadata

The final image URL must be publicly reachable by the service generating a preview. Add the appropriate metadata to the page that corresponds to the Markdown entry. A typical Open Graph setup looks like this; replace the example URL and dimensions with the actual generated image details:

<meta property="og:title" content="How to Generate Social Cards from Markdown Content">
<meta property="og:description" content="A practical guide to Markdown-driven social preview images.">
<meta property="og:type" content="article">
<meta property="og:image" content="https://example.com/social/generate-social-cards.png">
<meta property="og:image:alt" content="A social card for the article">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://example.com/social/generate-social-cards.png">

Generate these values from the same content record used by the card template. That keeps the title and image aligned when content changes. Framework conventions may emit metadata for you; inspect the rendered page head to confirm the actual tags and image URL.

7. Verify a deployed page

  1. Open the deployed page and inspect its rendered metadata. Confirm the image URL is the intended one.
  2. Request the image URL directly. Confirm it works without login and returns an image with the expected MIME type and dimensions.
  3. Check the image’s file size and text layout, including a long title and any optional fields that are absent.
  4. Use the target social network or messaging app’s current preview checker, when available, and inspect the preview for the deployed page URL.
  5. After changing a card, verify the generated image and page metadata again. Build caches and crawler caches may affect what a preview shows.

Preview caching and refresh timing vary by platform. The framework documentation does not establish one cache-refresh schedule for every network or messaging app, so check the target platform’s current guidance when a preview appears stale.

Common problems and fixes

Symptom Likely cause What to check
No preview image The page metadata is missing, points elsewhere, or the image is inaccessible. Inspect the deployed page head and open the image URL without authentication.
Old card still appears A build or crawler cache may still hold an earlier image or metadata. Confirm the deployed HTML and image first, then use the target platform’s current refresh or preview tools.
Title is clipped or awkwardly wrapped The template has no policy for long titles or line breaks. Test long and short titles; adjust wrapping, font size, or a deliberate title-length fallback.
Card shows literal Markdown Raw Markdown text was passed directly to the image template. Use frontmatter fields or convert content to plain text before rendering.
Generated route fails on deployment The renderer, runtime, or route behavior is incompatible with the selected host. Check framework and deployment documentation; use build-time output where a server runtime is unavailable.
Image is rejected or missing on one platform That platform may have format, size, crawler-access, or metadata rules that differ. Check its current requirements, response MIME type, file size, and public access.

Performance, reliability, and cost

Build-time generation makes a card reproducible with the content build and avoids needing a request-time renderer to create each image. Its tradeoff is that changed content requires a new build and deployment. Request-time generation can reflect current route data, but adds runtime dependencies and makes caching and failure handling part of the design. The reviewed framework sources do not provide an apples-to-apples speed or cost comparison, so choose based on your deployment and freshness needs.

Keep a stable, public image URL, and ensure a failed image render does not silently leave metadata pointing to a nonexistent file. For request-time routes, decide how errors and cached results should behave in the runtime you use. Test crawler access from the deployed environment rather than assuming local development behavior proves public availability.

Or skip the browser setup

If your workflow needs a screenshot of a rendered page or element as part of producing visual content, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can return PNG, JPEG, WebP, or PDF with one GET request. For social-card artwork itself, a designed template gives you control over the card layout; a screenshot API is useful when the card should reflect a rendered page.

For example, capture a page as WebP:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for request options. Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan.

Sign up for 1,000 free screenshots a month, no card required.

FAQ

Should a social card contain the whole Markdown post?

Usually, use the title and a few intentional frontmatter fields. A card is a preview, and raw Markdown includes formatting that may not fit the design.

Does generating an image automatically add it to the page preview?

No. The page needs metadata that points to the publicly reachable image, unless a framework convention generates that metadata for you. Check the rendered page head.

Can one template serve every Markdown page?

Yes. A shared template can accept fields from each entry, with defaults and layout rules for missing or unusually long values.

How do I know when a social preview will update?

There is no universal refresh schedule established by the reviewed sources. Check the target platform’s current preview tools and guidance.

Sources