Animated Open Graph images (the practical version)
Most platforms still want a static og:image. A handful — Discord, Telegram, Slack — preview MP4s. Here's how to serve both from one source.
The Open Graph protocol shipped with og:image and stopped there. A decade later, "og:image" is still 99% of the social preview market — Facebook, LinkedIn, Twitter, Threads, Bluesky all want a static 1200×630 PNG or JPG.
But the long tail of platforms — Discord, Telegram, Slack, iMessage — now preview short MP4s when the page exposes one. The og:video tag has existed since the beginning; it's only now becoming meaningful. If your og:image is built in HTML, getting an animated version is essentially free.
The two outputs
You need both:
- A static
og:image(1200×630 PNG/JPG) for the platforms that ignore video. - An animated
og:video(1200×630 MP4, 3-6 seconds, no audio, loops cleanly) for the platforms that don't.
The static one is the last frame of the animated one. If you author them together, they stay in sync forever.
The HTML source
Build the OG card as a single HTML file with a render(t) function. Title slides in, subtitle follows, a brand bar wipes across the bottom, settle.
The pipeline
A request for /og/{post-slug} produces both outputs from the same render path:
- HTML. Server-render the OG template with the post-specific variables (title, subtitle, brand color).
- MP4. Headless Chromium runs the 6-second
render(t)loop and emits a 1200×630 MP4. Cache it. - PNG. Same render at
t = 6.0(the settled state), captured once. Cache it.
The post's <head> ends up with:
<meta property="og:image" content="/og/post-slug.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:video" content="/og/post-slug.mp4" />
<meta property="og:video:type" content="video/mp4" />
<meta property="og:video:width" content="1200" />
<meta property="og:video:height" content="630" />The platforms that prefer video pick up the video; the ones that don't fall through to the image.
The constraints worth knowing
Duration: 3-6 seconds. Long enough for one motion beat, short enough for a chat preview. Anything longer feels like an ad.
Loop cleanly. The platforms that loop the video do not crossfade. The last frame and the first frame should be visually identical — or close enough that the eye doesn't catch the jump.
No audio. Most social preview players are muted by default; some refuse to play video with audio at all.
Codec: h.264 baseline. Maximum compatibility. Don't ship h.265 or AV1 to a Discord embed.
Size: under 8 MB. Most platforms cap at 8 MB; some at 4 MB. A clean 1200×630 6-second h.264 typically lands around 2 MB.
Per-post automation
This is the real win. With an HTML template and a renderer in CI, every blog post gets a custom OG card and OG video for free. The render runs as part of the build; the outputs are written to /og/{slug}.png and /og/{slug}.mp4. No per-post design work, no AE export, no separate asset pipeline.
The longer "render OG in code" argument is in social media cards every ratio. The render-from-Next.js-route flavor is in render video from a Next.js route.
A practical close
The reason most OG cards look bad isn't aesthetic — it's that they were drawn once by a designer for the homepage and never updated for the long tail of posts. An HTML template behind a server route fixes that. The animated version is the same template with a render(t) function. You get both for the price of one.
Cite this postBibTeX · APA · Markdown
@misc{park2026animated,
author = {Ren Park},
title = {Animated Open Graph images (the practical version)},
year = {2026},
url = {https://hyperframes.video/blog/animated-open-graph-images},
note = {HyperFrames blog}
}Ren Park. (2026, May 19). Animated Open Graph images (the practical version). HyperFrames. https://hyperframes.video/blog/animated-open-graph-images
[Animated Open Graph images (the practical version)](https://hyperframes.video/blog/animated-open-graph-images) — Ren Park, 2026
Ren writes guides, runs workshops, and breaks the CLI on purpose so you do not have to. Previously dev rel at a CI company; before that, an actual filmmaker.
Animated quote cards for Twitter (and other platforms)
A quote-card generator that produces a still PNG and a short animated MP4 from one HTML template. Same source, every social size.
Twitter / X video card generator (the HTML version)
X expanded its Card spec to support short MP4 previews. Here's how to generate one per post, automatically, from an HTML template.
Animated app onboarding screens to MP4
Build an animated app onboarding video in HTML — three-screen carousel with sliding screens, fading headlines, scaling illustrations, advancing dots — and render to MP4.
Building with HyperFrames? Come hang out.
We're on GitHub, in Discord, and the playground is one click away. Bring weird ideas — we collect them.