This is dynamic-thumbnail-service-v2. It's X5 faster compared to the previous version.
In this version, we no longer use Puppeteer (a headless browser) to capture HTML and then return images. Instead, we utilize the @vercel/og library, which employs Satori as its core engine.
(Satori: Enlightened library is used to convert HTML and CSS into SVG))
Run
pnpm install
pnpm run devdocker run -p 3001:3000 huanttok/dynamic-thumbnail-service-v2:latestNow service is live on http://localhost:3001
Available endpoints
1/ API debug html
GET: /article/thumbnail/html
Params:
- title: your article title
- author: author name
- avatar: avatar url
2/ API thumbnail image
GET: /article/thumbnail/article
Params:
- title: your article title
- author: author name
- avatar: avatar url
- debug: true/false
Insert the following meta tag into your website:
<meta property="og:image" content="http://dynamic-thumbnail-service/article/thumbnail?title={TITLE}&author={AUTHOR}&avatar={AVATAR}">Now, when user share your page to Twitter, Facebook, or Slack chat,... you will see this thumbnail:
You can use Facebook debug tool to preview.
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.
Available CSS features
| Property | Property Expanded | Supported Values | Example | 
|---|---|---|---|
| display | noneandflex, default toflex | ||
| position | relativeandabsolute, default torelative | ||
| color | Supported | ||
| margin | |||
| marginTop | Supported | ||
| marginRight | Supported | ||
| marginBottom | Supported | ||
| marginLeft | Supported | ||
| Position | |||
| top | Supported | ||
| right | Supported | ||
| bottom | Supported | ||
| left | Supported | ||
| Size | |||
| width | Supported | ||
| height | Supported | ||
| Min & max size | |||
| minWidth | Supported except for min-contentandmax-content | ||
| minHeight | Supported except for min-contentandmax-content | ||
| maxWidth | Supported except for min-contentandmax-content | ||
| maxHeight | Supported except for min-contentandmax-content | ||
| border | |||
| Width ( borderWidth,borderTopWidth, ...) | Supported | ||
| Style ( borderStyle,borderTopStyle, ...) | solidanddashed, default tosolid | ||
| Color ( borderColor,borderTopColor, ...) | Supported | ||
| Shorthand ( border,borderTop, ...) | Supported, i.e. 1px solid gray | ||
| borderRadius | |||
| borderTopLeftRadius | Supported | ||
| borderTopRightRadius | Supported | ||
| borderBottomLeftRadius | Supported | ||
| borderBottomRightRadius | Supported | ||
| Shorthand | Supported, i.e. 5px,50% / 5px | ||
| Flex | |||
| flexDirection | column,row,row-reverse,column-reverse, default torow | ||
| flexWrap | wrap,nowrap,wrap-reverse, default towrap | ||
| flexGrow | Supported | ||
| flexShrink | Supported | ||
| flexBasis | Supported except for auto | ||
| alignItems | stretch,center,flex-start,flex-end,baseline,normal, default tostretch | ||
| alignContent | Supported | ||
| alignSelf | Supported | ||
| justifyContent | Supported | ||
| gap | Supported | ||
| Font | |||
| fontFamily | Supported | ||
| fontSize | Supported | ||
| fontWeight | Supported | ||
| fontStyle | Supported | ||
| Text | |||
| tabSize | Supported | ||
| textAlign | start,end,left,right,center,justify, default tostart | ||
| textTransform | none,lowercase,uppercase,capitalize, defaults tonone | ||
| textOverflow | clip,ellipsis, defaults toclip | ||
| textDecoration | Support line types underlineandline-through, and stylesdotted,dashed,solid | Example | |
| textShadow | Supported | ||
| lineHeight | Supported | ||
| letterSpacing | Supported | ||
| whiteSpace | normal,pre,pre-wrap,pre-line,nowrap, defaults tonormal | ||
| wordBreak | normal,break-all,break-word,keep-all, defaults tonormal | ||
| textWrap | wrap,balance, defaults towrap | ||
| Background | |||
| backgroundColor | Supported, single value | ||
| backgroundImage | linear-gradient,radial-gradient,url, single value | ||
| backgroundPosition | Support single value | ||
| backgroundSize | Support two-value size i.e. `10px 20%` | ||
| backgroundClip | border-box,text | ||
| backgroundRepeat | repeat,repeat-x,repeat-y,no-repeat, defaults torepeat | ||
| transform | |||
| Translate ( translate,translateX,translateY) | Supported | ||
| Rotate | Supported | ||
| 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 tonone | ||
| opacity | Supported | ||
| boxShadow | Supported | ||
| overflow | visibleandhidden, default tovisible | ||
| filter | Supported | ||
| clipPath | Supported | Example | |
| lineClamp | Supported | Example | |
| Mask | |||
| maskImage | linear-gradient(...),radial-gradient(...),url(...) | Example | |
| maskPosition | Supported | Example | |
| maskSize | Support two-value size i.e. `10px 20%` | Example | |
| maskRepeat | repeat,repeat-x,repeat-y,no-repeat, defaults torepeat | Example | |
View up-to-date list here: https://github.com/vercel/satori#css