• Stars
    star
    10,131
  • Rank 3,236 (Top 0.07 %)
  • Language
    TypeScript
  • License
    Mozilla Public Li...
  • Created about 2 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Enlightened library to convert HTML and CSS to SVG

Satori

Satori: Enlightened library to convert HTML and CSS to SVG.

Note

To use Satori in your project to generate PNG images like Open Graph images and social cards, check out our announcement and Vercel’s Open Graph Image Generation →

To use it in Next.js, take a look at the Next.js Open Graph Image Generation template →

Overview

Satori supports the JSX syntax, which makes it very straightforward to use. Here’s an overview of the basic usage:

// api.jsx
import satori from 'satori'

const svg = await satori(
  <div style={{ color: 'black' }}>hello, world</div>,
  {
    width: 600,
    height: 400,
    fonts: [
      {
        name: 'Roboto',
        // Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
        data: robotoArrayBuffer,
        weight: 400,
        style: 'normal',
      },
    ],
  },
)

Satori will render the element into a 600×400 SVG, and return the SVG string:

'<svg ...><path d="..." fill="black"></path></svg>'

Under the hood, it handles layout calculation, font, typography and more, to generate a SVG that matches the exact same HTML and CSS in a browser.


Documentation

JSX

Satori only accepts JSX elements that are pure and stateless. You can use a subset of HTML elements (see section below), or custom React components, but React APIs such as useState, useEffect, dangerouslySetInnerHTML are not supported.

Use without JSX

If you don't have JSX transpiler enabled, you can simply pass React-elements-like objects that have type, props.children and props.style (and other properties too) directly:

await satori(
  {
    type: 'div',
    props: {
      children: 'hello, world',
      style: { color: 'black' },
    },
  },
  options
)

HTML Elements

Satori supports a limited subset of HTML and CSS features, due to its special use cases. In general, only these static and visible elements and properties that are implemented.

For example, the <input> HTML element, the cursor CSS property are not in consideration. And you can't use <style> tags or external resources via <link> or <script>.

Also, Satori does not guarantee that the SVG will 100% match the browser-rendered HTML output since Satori implements its own layout engine based on the SVG 1.1 spec.

You can find the list of supported HTML elements and their preset styles here.

Images

You can use <img> to embed images. However, width, and height attributes are recommended to set:

await satori(
  <img src="https://picsum.photos/200/300" width={200} height={300} />,
  options
)

When using background-image, the image will be stretched to fit the element by default if you don't specify the size.

If you want to render the generated SVG to another image format such as PNG, it would be better to use base64 encoded image data (or buffer) directly as props.src so no extra I/O is needed in Satori:

await satori(
  <img src="data:image/png;base64,..." width={200} height={300} />,
  // Or src={arrayBuffer}, src={buffer}
  options
)

CSS

Satori uses the same Flexbox layout engine as React Native, and it’s not a complete CSS implementation. However, it supports a subset of the spec that covers most common CSS features:

Property Property Expanded Supported Values Example
display none and flex, default to flex
position relative and absolute, default to relative
color Supported
margin
marginTopSupported
marginRightSupported
marginBottomSupported
marginLeftSupported
Position
topSupported
rightSupported
bottomSupported
leftSupported
Size
widthSupported
heightSupported
Min & max size
minWidthSupported except for min-content and max-content
minHeightSupported except for min-content and max-content
maxWidthSupported except for min-content and max-content
maxHeightSupported except for min-content and max-content
border
Width (borderWidth, borderTopWidth, ...)Supported
Style (borderStyle, borderTopStyle, ...)solid and dashed, default to solid
Color (borderColor, borderTopColor, ...)Supported
Shorthand (border, borderTop, ...)Supported, i.e. 1px solid gray
borderRadius
borderTopLeftRadiusSupported
borderTopRightRadiusSupported
borderBottomLeftRadiusSupported
borderBottomRightRadiusSupported
ShorthandSupported, i.e. 5px, 50% / 5px
Flex
flexDirectioncolumn, row, row-reverse, column-reverse, default to row
flexWrapwrap, nowrap, wrap-reverse, default to wrap
flexGrowSupported
flexShrinkSupported
flexBasisSupported except for auto
alignItemsSupported
alignContentSupported
alignSelfSupported
justifyContentSupported
gapSupported
Font
fontFamilySupported
fontSizeSupported
fontWeightSupported
fontStyleSupported
Text
tabSizeSupported
textAlignstart, end, left, right, center, justify, default to start
textTransformnone, lowercase, uppercase, capitalize, defaults to none
textOverflowclip, ellipsis, defaults to clip
textDecorationSupport line types underline and line-through, and styles dotted, dashed, solidExample
textShadowSupported
lineHeightSupported
letterSpacingSupported
whiteSpacenormal, pre, pre-wrap, pre-line, nowrap, defaults to normal
wordBreaknormal, break-all, break-word, keep-all, defaults to normal
textWrapwrap, balance, defaults to wrap
Background
backgroundColorSupported, single value
backgroundImagelinear-gradient, radial-gradient, url, single value
backgroundPositionSupport single value
backgroundSizeSupport two-value size i.e. `10px 20%`
backgroundClipborder-box, text
backgroundRepeatrepeat, repeat-x, repeat-y, no-repeat, defaults to repeat
transform
Translate (translate, translateX, translateY)Supported
RotateSupported
Scale (scale, scaleX, scaleY)Supported
Skew (skew, skewX, skewY)Supported
transformOrigin Support one-value and two-value syntax (both relative and absolute values)
objectFit contain, cover, none, default to none
opacity Supported
boxShadow Supported
overflow visible and hidden, default to visible
filter Supported
clipPath Supported Example
lineClamp Supported Example
Mask
maskImagelinear-gradient(...), radial-gradient(...), url(...)Example
maskPositionSupportedExample
maskSizeSupport two-value size i.e. `10px 20%`Example
maskRepeatrepeat, repeat-x, repeat-y, no-repeat, defaults to repeatExample

Note:

  1. Three-dimensional transforms are not supported.
  2. There is no z-index support in SVG. Elements that come later in the document will be painted on top.
  3. box-sizing is set to border-box for all elements.
  4. calc isn't supported.
  5. overflow: hidden and transform can't be used together.
  6. currentcolor support is only available for the color property.

Language and Typography

Advanced typography features such as kerning, ligatures and other OpenType features are not currently supported.

RTL languages are not supported either.

Fonts

Satori currently supports three font formats: TTF, OTF and WOFF. Note that WOFF2 is not supported at the moment. You must specify the font if any text is rendered with Satori, and pass the font data as ArrayBuffer (web) or Buffer (Node.js):

await satori(
  <div style={{ fontFamily: 'Inter' }}>Hello</div>,
  {
    width: 600,
    height: 400,
    fonts: [
      {
        name: 'Inter',
        data: inter,
        weight: 400,
        style: 'normal',
      },
      {
        name: 'Inter',
        data: interBold,
        weight: 700,
        style: 'normal',
      },
    ],
  }
)

Multiple fonts can be passed to Satori and used in fontFamily.

Emojis

To render custom images for specific graphemes, you can use graphemeImages option to map the grapheme to an image source:

await satori(
  <div>Next.js is 🤯!</div>,
  {
    ...,
    graphemeImages: {
      '🤯': 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/1f92f.svg',
    },
  }
)

The image will be resized to the current font-size (both width and height) as a square.

Locales

Satori supports rendering text in different locales. You can specify the supported locales via the lang attribute:

await satori(
  <div lang="ja-JP">骨</div>
)

Same characters can be rendered differently in different locales, you can specify the locale when necessary to force it to render with a specific font and locale. Check out this example to learn more.

Supported locales are exported as the Locale enum type.

Dynamically Load Emojis and Fonts

Satori supports dynamically loading emoji images (grapheme pictures) and fonts. The loadAdditionalAsset function will be called when a text segment is rendered but missing the image or font:

await satori(
  <div>👋 你好</div>,
  {
    // `code` will be the detected language code, `emoji` if it's an Emoji, or `unknown` if not able to tell.
    // `segment` will be the content to render.
    loadAdditionalAsset: async (code: string, segment: string) => {
      if (code === 'emoji') {
        // if segment is an emoji
        return `data:image/svg+xml;base64,...`
      }

      // if segment is normal text
      return loadFontFromSystem(code)
    }
  }
)

Runtime and WASM

Satori can be used in browser, Node.js (>= 16), and Web Workers.

By default, Satori depends on asm.js for the browser runtime, and native module in Node.js. However, you can optionally load WASM instead by importing satori/wasm and provide the initialized WASM module instance of Yoga to Satori:

import satori, { init } from 'satori/wasm'
import initYoga from 'yoga-wasm-web'

const yoga = initYoga(await fetch('/yoga.wasm').then(res => res.arrayBuffer()))
init(yoga)

await satori(...)

When running in the browser or in the Node.js environment, WASM files need to be hosted and fetched before initializing. asm.js can be bundled together with the lib. In this case WASM should be faster.

When running on the Node.js server, native modules should be faster. However there are Node.js environments where native modules are not supported (e.g. StackBlitz's WebContainers), or other JS runtimes that support WASM (e.g. Vercel's Edge Runtime, Cloudflare Workers, or Deno).

Additionally, there are other difference between asm.js, native and WASM, such as security and compatibility.

Overall there are many trade-offs between each choice, and it's better to pick the one that works the best for your use case.

Font Embedding

By default, Satori renders the text as <path> in SVG, instead of <text>. That means it embeds the font path data as inlined information, so succeeding processes (e.g. render the SVG on another platform) don’t need to deal with font files anymore.

You can turn off this behavior by setting embedFont to false, and Satori will use <text> instead:

const svg = await satori(
  <div style={{ color: 'black' }}>hello, world</div>,
  {
    ...,
    embedFont: false,
  },
)

Debug

To draw the bounding box for debugging, you can pass debug: true as an option:

const svg = await satori(
  <div style={{ color: 'black' }}>hello, world</div>,
  {
    ...,
    debug: true,
  },
)

Contribute

You can use the Vercel OG Image Playground to test and report bugs of Satori. Please follow our contribution guidelines before opening a Pull Request.


Author


More Repositories

1

next.js

The React Framework
JavaScript
120,483
star
2

hyper

A terminal built on web technologies
TypeScript
42,467
star
3

swr

React Hooks for Data Fetching
TypeScript
29,423
star
4

turbo

Incremental bundler and build system optimized for JavaScript and TypeScript, written in Rust – including Turbopack and Turborepo.
Rust
24,396
star
5

pkg

Package your Node.js project into an executable
JavaScript
24,151
star
6

vercel

Develop. Preview. Ship.
TypeScript
11,950
star
7

micro

Asynchronous HTTP microservices
TypeScript
10,525
star
8

commerce

Next.js Commerce
TypeScript
10,203
star
9

serve

Static file serving and directory listing
TypeScript
9,088
star
10

ncc

Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.
JavaScript
8,786
star
11

ai

Build AI-powered applications with React, Svelte, Vue, and Solid
TypeScript
7,728
star
12

styled-jsx

Full CSS support for JSX without compromises
JavaScript
7,577
star
13

nextjs-subscription-payments

Clone, deploy, and fully customize a SaaS subscription application with Next.js.
TypeScript
5,334
star
14

platforms

A full-stack Next.js app with multi-tenancy and custom domain support. Built with Next.js App Router and the Vercel Domains API.
TypeScript
5,016
star
15

ms

Tiny millisecond conversion utility
TypeScript
4,912
star
16

ai-chatbot

A full-featured, hackable Next.js AI chatbot built by Vercel
TypeScript
4,873
star
17

og-image

Open Graph Image as a Service - generate cards for Twitter, Facebook, Slack, etc
TypeScript
4,031
star
18

release

Generate changelogs with a single command
JavaScript
3,544
star
19

examples

Enjoy our curated collection of examples and solutions. Use these patterns to build your own robust and scalable applications.
TypeScript
3,288
star
20

next-learn

Learn Next.js Starter Code
TypeScript
3,181
star
21

hazel

Lightweight update server for Electron apps
JavaScript
2,855
star
22

next-plugins

Official Next.js plugins
2,676
star
23

app-playground

https://app-dir.vercel.app/
TypeScript
2,226
star
24

virtual-event-starter-kit

Open source demo that Next.js developers can clone, deploy, and fully customize for events.
TypeScript
2,115
star
25

geist-font

1,846
star
26

async-retry

Retrying made simple, easy and async
JavaScript
1,780
star
27

arg

Simple argument parsing
JavaScript
1,191
star
28

react-tweet

Embed tweets in your React application.
TypeScript
1,188
star
29

nft

Node.js dependency tracing utility
JavaScript
1,182
star
30

avatar

💎 Beautiful avatars as a microservice
TypeScript
1,065
star
31

style-guide

Vercel's engineering style guide
JavaScript
1,064
star
32

next-react-server-components

Demo repository for Next.js + React Server Components
JavaScript
962
star
33

nextjs-postgres-nextauth-tailwindcss-template

Admin dashboard template.
TypeScript
797
star
34

nextjs-postgres-auth-starter

Next.js + Tailwind + Typescript + Drizzle + NextAuth + PostgreSQL starter template.
TypeScript
743
star
35

edge-runtime

Developing, testing, and defining the runtime Web APIs for Edge infrastructure.
TypeScript
736
star
36

server-components-notes-demo

Experimental demo of React Server Components with Next.js. Deployed serverlessly on Vercel.
TypeScript
723
star
37

micro-dev

The development environment for `micro`
JavaScript
695
star
38

nextgram

A sample Next.js app showing dynamic routing with modals as a route.
TypeScript
681
star
39

nextjs-portfolio-starter

Easily create a portfolio with Next.js and Markdown.
JavaScript
635
star
40

react-keyframes

Create frame-based animations in React
TypeScript
615
star
41

hyperpower

Hyper particle effects extension
JavaScript
613
star
42

static-fun

A fun demo for wildcard domains
TypeScript
610
star
43

async-sema

Semaphore using `async` and `await`
TypeScript
602
star
44

title

A service for capitalizing your title properly
JavaScript
576
star
45

fetch

Opinionated `fetch` (with retrying and DNS caching) optimized for use with Node.js
JavaScript
564
star
46

serve-handler

The foundation of `serve`
JavaScript
545
star
47

vrs

A serverless virtual reality e-commerce experience powered by Vercel
TypeScript
517
star
48

swr-site

The official website for SWR.
MDX
464
star
49

fun

ƒun - Local serverless function λ development runtime
TypeScript
462
star
50

storage

Vercel Postgres, KV, Blob, and Edge Config
TypeScript
455
star
51

mongodb-starter

A developer directory built on Next.js and MongoDB Atlas, deployed on Vercel with the Vercel + MongoDB integration.
TypeScript
438
star
52

spr-landing

Serverless Pre-Rendering Landing Page
CSS
426
star
53

hyper-site

The official website for the Hyper terminal
JavaScript
419
star
54

pkg-fetch

A utility to fetch or build patched Node binaries used by `pkg` to generate executables. This repo hosts prebuilt binaries in Releases.
TypeScript
412
star
55

analytics

Privacy-friendly, real-time traffic insights
TypeScript
384
star
56

sveltekit-commerce

SvelteKit Commerce
Svelte
357
star
57

reactions

Next.js Incremental Static Regeneration Demo
JavaScript
308
star
58

email-prompt

CLI email prompt with autocompletion and built-in validation
JavaScript
275
star
59

uid-promise

Creates a cryptographically strong UID
TypeScript
250
star
60

fetch-retry

Wrapper around `fetch` with sensible retrying defaults
JavaScript
220
star
61

git-hooks

No nonsense Git hook management
JavaScript
198
star
62

zsh-theme

Yet another zsh theme
178
star
63

remote-cache

The Vercel Remote Cache SDK
TypeScript
169
star
64

cosmosdb-server

A Cosmos DB server implementation for testing your applications locally.
TypeScript
167
star
65

update-check

Minimalistic update notifications for command line interfaces
JavaScript
157
star
66

test-listen

Quick ephemeral URLs for your tests
JavaScript
153
star
67

install-node

Simple one-liner shell script that installs official Node.js binaries
Shell
136
star
68

terraform-provider-vercel

Terraform Vercel Provider
Go
129
star
69

title-site

A website for capitalizing your titles
JavaScript
123
star
70

preview-mode-demo

This demo showcases Next.js' next-gen Static Site Generation (SSG) support.
TypeScript
105
star
71

nextjs-discord-bot

Discord bot for the official Next.js Discord
TypeScript
100
star
72

beginner-sveltekit

The complete course to start your journey building Svelte applications.
JavaScript
97
star
73

err-sh

Microservice that forwards you to error messages
JavaScript
96
star
74

community

Welcome to the Vercel Community. Discuss feature requests, ask questions, and connect with others in the community.
96
star
75

webpack-asset-relocator-loader

Used in ncc while emitting and relocating any asset references
JavaScript
95
star
76

commerce-framework

TypeScript
94
star
77

hyperyellow

Example theme for hyperterm
JavaScript
87
star
78

schemas

All schemas used for validation that are shared between our projects
JavaScript
78
star
79

nuxt3-kitchen-sink

An example template showing all Nuxt 3 features on Vercel.
Vue
64
star
80

next-codemod

codemod transformations to help upgrade Next.js codebases
JavaScript
63
star
81

react-transition-progress

Show a progress bar while React Transitions run
TypeScript
57
star
82

otel

TypeScript
54
star
83

opentelemetry-collector-dev-setup

Shell
50
star
84

async-listen

Promisify server.listen for your HTTP/HTTPS/TCP server.
TypeScript
45
star
85

wait-for

Small utility that waits for a file to exist and optionally have some permissions set.
C
44
star
86

tracing-js

An implementation of Opentracing API for honeycomb.io
TypeScript
43
star
87

dns-cached-resolve

Caching DNS resolver
TypeScript
40
star
88

example-integration

TypeScript
38
star
89

fetch-cached-dns

A decorator on top of `fetch` that caches the DNS query
JavaScript
35
star
90

speed-insights

Vercel Speed Insights package
TypeScript
30
star
91

remark-capitalize

Transform all markdown titles with title.sh
JavaScript
29
star
92

resolve-node

API endpoint to resolve an arbitrary Node.js version with semver support
JavaScript
29
star
93

cra-to-next

An example of migrating Create React App to Next.js.
JavaScript
24
star
94

ng-deploy-vercel

Deploy Angular applications to Vercel
TypeScript
22
star
95

stripe-integration

A Vercel deploy integration to automatically set up your Stripe API keys and webhook secrets.
TypeScript
21
star
96

rcurl

`curl --resolve` helper script
Shell
21
star
97

release-auth

Handles the authentication for `release`
JavaScript
21
star
98

gatsby-plugin-vercel

Track Core Web Vitals in Gatsby projects with Vercel Analytics.
JavaScript
20
star
99

cert-demo

TypeScript
19
star
100

go-bridge

Bridge for `@vercel/go`
Go
18
star