API „HTML na obrazek” składa twój kod i CSS w przeglądarce i oddaje zdjęcie wyniku. W Shareglint zapisujesz HTML i CSS raz, jako szablon; potem każdy obrazek to jedno żądanie HTTP — POST /v1/images z nazwą szablonu i tekstem, który się zmienia — a w odpowiedzi dostajesz adres pliku PNG, JPEG, WebP albo PDF, zwykle po około sekundzie.
To prawdziwy Chrome, a nie odtworzony CSS: grid, flexbox, gradienty, cienie, emoji i tekst od prawej do lewej wychodzą tak jak w twojej przeglądarce. Wypróbuj to niżej, bez zakładania konta.
Zmień HTML i CSS, potem wyrenderuj. Dostaniesz PNG 1200×630 z tego samego Chrome, który renderuje obrazki z API.
Zacznij za darmo — 100 obrazków miesięcznie
Podgląd pozwala na 5 renderów na godzinę z jednego adresu i dodaje znak wodny planu Free. Skrypty, formularze, ramki iframe i SVG są usuwane, tak samo jak każdy zewnętrzny adres — obrazki i fonty z innych serwerów się nie wczytają (adresy data: tak). Te same zasady obowiązują zapisane szablony.
Dwa wywołania na start, potem jedno na każdy obrazek.
Podczas projektowania POST /v1/templates/preview renderuje szkic bez zapisywania i nie zużywa limitu.
Każdy przykład zapisuje szablon i renderuje jeden PNG. Zamień sk_live_YOUR_KEY na swój klucz z panelu.
curl
# 1. Save the template once
curl -X POST "https://shareglint.com/v1/templates" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Article card",
"width": 1200,
"height": 630,
"fields": [
"kicker",
"title",
"author"
],
"html": "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
"css": ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}"
}'
# → {"id": "tpl_…", "slug": "article-card", …}
# 2. One call per image (use the slug from step 1)
curl -X POST "https://shareglint.com/v1/images?wait=true" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "article-card",
"format": "png",
"modifications": {
"kicker": "Engineering",
"title": "How we cut our build time in half",
"author": "Ada Lovelace"
}
}'
JavaScript
const API = 'https://shareglint.com/v1';
const headers = {
Authorization: 'Bearer sk_live_YOUR_KEY',
'Content-Type': 'application/json',
};
// 1. Save the template once
const template = await fetch(`${API}/templates`, {
method: 'POST',
headers,
body: JSON.stringify({
name: "Article card",
width: 1200,
height: 630,
fields: ['kicker', 'title', 'author'],
html: "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
css: ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}",
}),
}).then((r) => r.json());
// 2. One call per image
const image = await fetch(`${API}/images?wait=true`, {
method: 'POST',
headers,
body: JSON.stringify({
template: template.slug,
format: 'png',
modifications: {
kicker: "Engineering",
title: "How we cut our build time in half",
author: "Ada Lovelace",
},
}),
}).then((r) => r.json());
console.log(image.url);
PHP (Laravel)
use Illuminate\Support\Facades\Http;
$api = Http::withToken('sk_live_YOUR_KEY')->baseUrl('https://shareglint.com/v1');
// 1. Save the template once
$template = $api->post('/templates', [
'name' => 'Article card',
'width' => 1200,
'height' => 630,
'fields' => ['kicker', 'title', 'author'],
'html' => '<div class="card"><p class="kicker">{{ kicker }}</p><div class="fitbox"><h1 class="fit" data-autofit>{{ title }}</h1></div><p class="by">{{ author }}</p></div>',
'css' => '.card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}',
])->json();
// 2. One call per image
$image = $api->post('/images?wait=true', [
'template' => $template['slug'],
'format' => 'png',
'modifications' => [
'kicker' => 'Engineering',
'title' => 'How we cut our build time in half',
'author' => 'Ada Lovelace',
],
])->json();
echo $image['url'];
Python
import requests
API = "https://shareglint.com/v1"
HEADERS = {"Authorization": "Bearer sk_live_YOUR_KEY"}
# 1. Save the template once
template = requests.post(f"{API}/templates", headers=HEADERS, json={
"name": "Article card",
"width": 1200,
"height": 630,
"fields": ["kicker", "title", "author"],
"html": "<div class=\"card\"><p class=\"kicker\">{{ kicker }}</p><div class=\"fitbox\"><h1 class=\"fit\" data-autofit>{{ title }}</h1></div><p class=\"by\">{{ author }}</p></div>",
"css": ".card{height:100%;padding:72px;display:grid;grid-template-rows:auto 1fr auto;gap:24px;background:#0f172a;color:#f8fafc;font-family:Roboto,sans-serif} .kicker{color:#fbbf24;font-size:26px;letter-spacing:.1em;text-transform:uppercase} h1{font-size:76px;line-height:1.08} .by{font-size:28px;color:#94a3b8}",
}).json()
# 2. One call per image
image = requests.post(f"{API}/images?wait=true", headers=HEADERS, json={
"template": template["slug"],
"format": "png",
"modifications": {
"kicker": "Engineering",
"title": "How we cut our build time in half",
"author": "Ada Lovelace",
},
}).json()
print(image["url"])
{
"id": "img_01m08s3ez1zcv28h335g9923bw",
"kind": "image",
"status": "completed",
"format": "png",
"size": "og",
"width": 1200,
"height": 630,
"url": "https://cdn.shareglint.com/renders/img_01m08s3ez1zcv28h335g9923bw.png",
"duration_ms": 912
}
| format | Co dostajesz |
|---|---|
png |
Bezstratny. scale 2 (domyślnie) podwaja piksele: szablon 1200×630 daje plik 2400×1260; scale 1 daje dokładnie 1200×630. |
jpeg |
Mniejsze pliki przy zdjęciach; jakość od 1 do 100, domyślnie 85. |
webp |
Jeszcze mniejsze, z tym samym ustawieniem jakości co JPEG. |
pdf |
Jedna strona dokładnie w rozmiarze szablonu, z tłami, tekst zostaje wektorowy i da się go zaznaczyć. |
gif, mp4 |
Animacja: nagrywa animacje CSS szablonu, do 5 sekund; każdy kosztuje 5 renderów z limitu. |
Jeden szablon renderuje się też w każdym gotowym rozmiarze (og 1200×630, square 1080×1080, portrait 1080×1350, story 1080×1920, pinterest 1000×1500, youtube 1280×720) — jaki rozmiar chce każda platforma.
Są trzy popularne sposoby, żeby samemu zamienić HTML na obrazek. Każdy działa; każdy ma koszt, który wychodzi później.
| Sposób | Jaki CSS renderuje | Co bierzesz na siebie |
|---|---|---|
| Satori / @vercel/og | Podzbiór: JSX z układem flexbox, bez CSS grid | Kartę piszesz w JSX, pliki fontów ładujesz sam, a całość chodzi w twojej funkcji Next.js albo edge |
| wkhtmltoimage | Stary silnik Qt WebKit: bez CSS grid, nowoczesny CSS zawodny | Narzędzie, którego projekt zarchiwizowano w 2023 roku, zainstalowane na twoich serwerach |
| Puppeteer albo Playwright na twoich serwerach | Wszystko, co renderuje Chrome | Pamięć i awarie Chrome, fonty na każdej maszynie, kolejka i izolowanie HTML-a, którego nie napisałeś |
| Shareglint | Wszystko, co renderuje Chrome | Jedno żądanie HTTP; Chrome, fonty, piaskownica, cache i przechowywanie są po naszej stronie |
Jeśli strona stoi na Next.js, a karta mieści się we flexboksie, @vercel/og jest darmowy i działa tuż obok twoich stron — bierz go. Własny Chrome ma sens, gdy już go utrzymujesz na dużą skalę. API opłaca się wtedy, gdy nie chcesz robić ani jednego, ani drugiego.
Free: 100 obrazków miesięcznie, bez karty, z małym znakiem wodnym. Starter: $9 miesięcznie za 2,000 obrazków ($4.50 za tysiąc), bez znaku wodnego. Render, który już masz — ten sam szablon, te same pola, ten sam format — wraca z cache i nie zużywa limitu.
Usługą sieciową, która bierze HTML i CSS, składa je w silniku przeglądarki i zwraca obraz wyniku — PNG, JPEG, WebP albo PDF. Przydaje się, gdy obrazek ma powstawać z danych: karty do mediów społecznościowych, certyfikaty, rachunki, wykresy z podpisami, banery do maili.
W Shareglint: zapisz HTML i CSS raz przez POST /v1/templates, potem wywołaj POST /v1/images?wait=true ze slugiem szablonu, wartościami pól i "format": "png". Odpowiedź zawiera adres PNG.
Tak. "format": "pdf" zwraca jedną stronę dokładnie w rozmiarze szablonu, z wydrukowanymi tłami i tekstem w wektorze, więc zostaje ostry i da się go zaznaczyć.
Grid, flexbox i reszta nowoczesnego CSS-a działają, bo rendererem jest Chrome. Fonty pochodzą z rodzin zainstalowanych w rendererze (Roboto, Open Sans, Carlito, DejaVu Sans, DejaVu Serif, DejaVu Sans Mono, Ubuntu, Noto Sans CJK JP, Noto Sans CJK SC, Noto Color Emoji); wgrywania własnych plików fontów nie ma.
Nie. Szablony są czyszczone przy zapisie i skrypty znikają — dzięki temu można bezpiecznie renderować HTML od kogokolwiek. Stronę, która potrzebuje swoich skryptów, zrzucisz przez Screenshot API z jej adresu.
Plan Free renderuje 100 obrazków miesięcznie bez karty, z małym znakiem wodnym. Podgląd na tej stronie nie wymaga nawet konta.
HTMLCSStoImage przyjmuje cały HTML w każdym żądaniu. Shareglint przechowuje szablon raz i przyjmuje tylko zmieniające się pola, dopasowuje długość tekstu, ma cache, który nie zużywa limitu, i 153 gotowych szablonów. Jeśli twój HTML jest za każdym razem inny, ich model pasuje lepiej.