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 |
none and flex, default to flex |
||
position |
relative and absolute, default to relative |
||
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-content and max-content | ||
minHeight | Supported except for min-content and max-content | ||
maxWidth | Supported except for min-content and max-content | ||
maxHeight | Supported 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 | |||
borderTopLeftRadius | Supported | ||
borderTopRightRadius | Supported | ||
borderBottomLeftRadius | Supported | ||
borderBottomRightRadius | Supported | ||
| Shorthand | Supported, i.e. 5px, 50% / 5px | ||
| Flex | |||
flexDirection | column, row, row-reverse, column-reverse, default to row | ||
flexWrap | wrap, nowrap, wrap-reverse, default to wrap | ||
flexGrow | Supported | ||
flexShrink | Supported | ||
flexBasis | Supported except for auto | ||
alignItems | stretch, center, flex-start, flex-end, baseline, normal, default to stretch | ||
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 to start | ||
textTransform | none, lowercase, uppercase, capitalize, defaults to none | ||
textOverflow | clip, ellipsis, defaults to clip | ||
textDecoration | Support line types underline and line-through, and styles dotted, dashed, solid | Example | |
textShadow | Supported | ||
lineHeight | Supported | ||
letterSpacing | Supported | ||
whiteSpace | normal, pre, pre-wrap, pre-line, nowrap, defaults to normal | ||
wordBreak | normal, break-all, break-word, keep-all, defaults to normal | ||
textWrap | wrap, balance, defaults to wrap | ||
| 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 to repeat | ||
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 to none |
||
opacity |
Supported | ||
boxShadow |
Supported | ||
overflow |
visible and hidden, default to visible |
||
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 to repeat | Example | |
View up-to-date list here: https://github.com/vercel/satori#css