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 dev
docker run -p 3001:3000 huanttok/dynamic-thumbnail-service-v2:latest
Now 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