Skip to content
/ migo Public

Generate dynamic OpenGraph images on Deno's Edge Network

License

Notifications You must be signed in to change notification settings

nberlette/migo

Repository files navigation

Click here for example OpenGraph Images



Generate dynamic OpenGraph images on Deno's Edge Network


Deploy with Deno


Schema

migo.deno.dev/:title.(png|svg)?:params
migo.deno.dev/:title/:subtitle.(png|svg)?:params
migo.deno.dev/:params/:title.(png|svg)
migo.deno.dev/:params/:title/:subtitle.(png|svg)

Features

  • Just-in-time rendered, globally deployed via Deno Deploy
  • Cached as immutable assets via Cloudflare for fast loads.
  • Rendered as .svg, rasterized to .png via resvg
  • Integrated with 100,000 icons via Iconify + icns.ml
  • Parameters for fine-grained control of image colors, dimensions, icon, and text.
  • TODO create a friendly GUI for image creation (see vercel)

Formats

Every image is initially sculpted as an SVG (Scalable Vector Graphics), and you can optionally add the extension .svg to force that format in the response.

Unfortunately most social media platforms don't support social images in SVG format yet, so requests without an .{svg,png} extension are redirected to .png prior to rendering.


Icons

Icons are embedded from icns, another Deno-powered project of mine. This means direct access to over 100,000 icons, and millions of color combinations. A great tool to browse the available icons and make a selection is icones by Anthony Fu.

To add an icon to an OG image, use the slug (in Iconify format) for the icon param, like so:

icon={collection}:{icon} (e.g. ?icon=tabler:brand-github).

You can also use an override iconUrl parameter, with an encoded URI you'd like to embed, e.g.:

icon=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fremojansen%2Flogo.ts%40master%2Fts.svg


Parameters

There are numerous parameters you can use to control the look and feel of the generated images. Parameters can be provided in either the first part of the path or in the query string of the URL.


Path (recommended)

For the best caching potential, I recommend only using the path-style parameters on your images. Some CDN providers have unexpected caching behavior when assets have query string parameters in their URI.

migo.deno.dev/bgColor=white&titleColor=black&icon=typescript/Title.png

Note: Allowed delimiters are & (ampersand), ; (semi-colon), or ::.


Query String

migo.deno.dev/title.png?bgColor=white&titleColor=black&icon=typescript

Note: Query string params must use the & (ampersand) delimiter.


Default Values

All available parameters and their default value (or formula used to calculate it):

// base props
width = 1280, 
height = 640, 
viewBox = "0 0 1280 640", 
pxRatio = 1.5, // set to 1 for low-res
bgColor = "white", 
borderRadius = 0, // rounded image corners

// icon
icon = "noto:t-rex", // set to false to disable icon
iconUrl = "https://icns.ml/{icon}.svg", 
iconW = 240, 
iconH = 240, // +iconW
iconX = 520, // ((width - iconW) / 2)
iconY = 60, // (iconH / 4)
iconColor = "black", // fill color
iconStroke = "none", // stroke color
iconStrokeWidth = 0, // stroke width

// title (first line of text)
titleX = 640, // (width / 2)
titleY = 450, // (iconH + iconY + (titleFontSize * 2.5))
titleFontSize = 64, 
titleFontFamily = "sans-serif", // "Inter"
titleFontWeight = "bold", 
titleColor = "#112233", // text color
titleStroke = "none", // stroke color
titleStrokeWidth = 0, // stroke width
titleTextAnchor = "middle", // text-anchor

// subtitle (second line of text)
subtitleX = 640, // (width / 2)
subtitleY = 530, // (titleY + (subtitleFontSize * 2.5))
subtitleFontSize = 32, 
// "serif" | "sans-serif" | "monospace"
subtitleFontFamily = "monospace",
subtitleFontWeight = "normal", 
subtitleColor = "#334455", // text color
subtitleStroke = "none", // stroke color
subtitleStrokeWidth = 0, // stroke width
subtitleTextAnchor = "middle" // text-anchor

Performance

The only lag you might encounter is the very first time an image is requested (this is unavoidable due to the render/raster steps). Thankfully, your users should essentially never be the ones encountering that lag time; they get a cache hit from their nearest edge datacenter.


Examples

Deno Module Starter

Nuxt Content Wind Starter

Creating Dynamic Social Cover Images