<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mukul Dutt</title>
    <description>The latest articles on DEV Community by Mukul Dutt (@paper_andbeyond).</description>
    <link>https://dev.to/paper_andbeyond</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4065105%2F0a8fcf42-20a6-4afa-861c-a5bf30fb6ceb.png</url>
      <title>DEV Community: Mukul Dutt</title>
      <link>https://dev.to/paper_andbeyond</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paper_andbeyond"/>
    <language>en</language>
    <item>
      <title>Open Graph Image API: generate dynamic og:image URLs in one call</title>
      <dc:creator>Mukul Dutt</dc:creator>
      <pubDate>Thu, 06 Aug 2026 05:12:48 +0000</pubDate>
      <link>https://dev.to/paper_andbeyond/open-graph-image-api-generate-dynamic-ogimage-urls-in-one-call-55c4</link>
      <guid>https://dev.to/paper_andbeyond/open-graph-image-api-generate-dynamic-ogimage-urls-in-one-call-55c4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://propzapi.com/blog/open-graph-image-api/" rel="noopener noreferrer"&gt;propzapi.com&lt;/a&gt; — cross-posted here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every one of your blog posts shares the same flat OG image. That's a thousand links on X and LinkedIn that all look identical, and forgettable. An Open Graph image API fixes that: one template, a per-page image.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;You store one 1200×630 layout with &lt;code&gt;{{variables}}&lt;/code&gt;, then sign a URL per post from that post's title. Drop the URL into &lt;code&gt;&amp;lt;meta property="og:image"&amp;gt;&lt;/code&gt;. The image renders the first time a crawler fetches it, then every refetch is cached and free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not @vercel/og?
&lt;/h2&gt;

&lt;p&gt;It's great if you're on Next.js and your card is simple. But it renders with Satori, a flexbox-only subset of CSS: no grid, no media queries, no pseudo-elements, and fonts limited to ttf/otf/woff with no ligatures. The day your design needs a font it won't load or a layout it won't do, you're rewriting. A full-Chromium API renders the CSS you already wrote.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost trap people miss
&lt;/h2&gt;

&lt;p&gt;Facebook, Slack, LinkedIn and X hammer your og:image on every share and re-share. If you paid per fetch, a viral post would be a surprise bill. Sign the URL for free, render once on first fetch (one credit), and cache serves every share after. Cost tracks how many distinct images you make, not how popular they get.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why isn't my og:image updating?
&lt;/h2&gt;

&lt;p&gt;Almost always platform caching, not your API. Facebook and LinkedIn scrape once and hold it — force a re-scrape in their debugger. And the URL has to be absolute; a relative path works in your browser but not for an external crawler.&lt;/p&gt;

&lt;p&gt;Full guide — sizes, the four ways to generate them, and the debugger workflow — in the &lt;a href="https://propzapi.com/blog/open-graph-image-api/" rel="noopener noreferrer"&gt;Open Graph Image API guide&lt;/a&gt;, built on &lt;a href="https://propzapi.com" rel="noopener noreferrer"&gt;propzapi&lt;/a&gt;, which also does HTML-to-image, screenshots, and one-page PDFs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>seo</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>HTML to PDF API: convert HTML to PDF in one call</title>
      <dc:creator>Mukul Dutt</dc:creator>
      <pubDate>Thu, 06 Aug 2026 05:09:58 +0000</pubDate>
      <link>https://dev.to/paper_andbeyond/html-to-pdf-api-convert-html-to-pdf-in-one-call-6dk</link>
      <guid>https://dev.to/paper_andbeyond/html-to-pdf-api-convert-html-to-pdf-in-one-call-6dk</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://propzapi.com/blog/html-to-pdf-api/" rel="noopener noreferrer"&gt;propzapi.com&lt;/a&gt; — cross-posted here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;wkhtmltopdf is dead. The repo was archived in 2023, the last release was 2020, and it ships an unpatched critical SSRF (CVE-2022-35583). If your PDF pipeline still runs on it, you're shipping a 2012 browser engine with a security hole. Here's the modern version.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an HTML to PDF API does
&lt;/h2&gt;

&lt;p&gt;You send HTML (or a stored template id plus data), it renders the page in headless Chromium, and returns a URL to a finished PDF. Chromium prints with the same engine that draws your page in a browser, so your flexbox, grid, and web fonts come out right — no 2012 WebKit fork mangling the layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  One call
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.propzapi.com/v1/images &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: pk_live_…"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"template":"tpl_…","format":"pdf","data":{"number":"1042","total":"$4,200.00"}}'&lt;/span&gt;
&lt;span class="c"&gt;# → { "url": "https://images.propzapi.com/img_….pdf", "width":794, "height":1123, "format":"pdf", "bytes":6679 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store an invoice or certificate template once with &lt;code&gt;{{variables}}&lt;/code&gt;, then render per record. A common wiring: a payment webhook fires, your handler POSTs the template with that order's data, and you email the returned PDF URL. Billed on delivery — a failed render costs nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gotchas that bite everyone
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Page size is CSS.&lt;/strong&gt; A4 is 794×1123px at 96dpi, US Letter is 816×1056. Set margins with the &lt;code&gt;@page&lt;/code&gt; rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backgrounds get stripped by default&lt;/strong&gt; — add &lt;code&gt;print-color-adjust: exact&lt;/code&gt; or your dark header prints white.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonts and images&lt;/strong&gt;: wait for webfonts to load before rendering, and use absolute URLs for anything the PDF shows (the render server has no session to authenticate with).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When not to reach for it
&lt;/h2&gt;

&lt;p&gt;For a 40-page contract with running headers, page numbers, and footnotes, use a paged-media engine like Prince — Chromium's page-break control is uneven. Chromium is built for single-page outputs: invoices, receipts, tickets, certificates, one-page reports.&lt;/p&gt;

&lt;p&gt;I wrote the full guide — self-host Puppeteer vs hosted, a comparison table, the WeasyPrint option, and every gotcha with its fix — in the &lt;a href="https://propzapi.com/blog/html-to-pdf-api/" rel="noopener noreferrer"&gt;HTML to PDF API guide&lt;/a&gt;, built on &lt;a href="https://propzapi.com" rel="noopener noreferrer"&gt;propzapi&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>node</category>
      <category>python</category>
    </item>
    <item>
      <title>Bannerbear alternative: a pay-as-you-go image generation API</title>
      <dc:creator>Mukul Dutt</dc:creator>
      <pubDate>Thu, 06 Aug 2026 05:07:00 +0000</pubDate>
      <link>https://dev.to/paper_andbeyond/bannerbear-alternative-a-pay-as-you-go-image-generation-api-4i6n</link>
      <guid>https://dev.to/paper_andbeyond/bannerbear-alternative-a-pay-as-you-go-image-generation-api-4i6n</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://propzapi.com/blog/bannerbear-alternative/" rel="noopener noreferrer"&gt;propzapi.com&lt;/a&gt; — cross-posted here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bannerbear is a good product. It's also a $49-a-month subscription and a visual editor, and neither of those is what every team wants. If you're a developer who renders images from data and would rather write HTML than click a canvas, here's the honest comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each one is
&lt;/h2&gt;

&lt;p&gt;Bannerbear is a mature no-code media platform: design in a drag-and-drop editor, then generate images, video, and PDFs over an API. It has real strengths I won't pretend away — a video API, AI face-detection (2 credits per image), Smart Crop, batch generation, and years of production maturity.&lt;/p&gt;

&lt;p&gt;propzapi is a developer-first image API: you store your own HTML/CSS templates with &lt;code&gt;{{variables}}&lt;/code&gt;, render them to PNG/JPEG/WebP/PDF in headless Chromium, screenshot any URL, and pay per image instead of a subscription. It ships a first-party MCP server, so an agent can render an image as a tool call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The price math
&lt;/h2&gt;

&lt;p&gt;Bannerbear's entry tier is $49/mo for 1,000 images (about $0.049 each), and you pay it whether you render 40 or 1,000. propzapi's $5 pack is about $0.033 an image and never expires — so 200 images is a few dollars, not a monthly floor. The subscription only pulls ahead once your steady volume clears a few hundred a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should pick which
&lt;/h2&gt;

&lt;p&gt;Choose Bannerbear if a non-developer owns the templates, you need video, or you want AI face-detection for user-uploaded photos. Choose propzapi if you render from data in code, want no monthly floor, and would rather write real CSS than work around an editor's limits.&lt;/p&gt;

&lt;p&gt;I did the full feature-by-feature table, the sourced capability breakdown (video, face-detect, Smart Crop — all from Bannerbear's own docs), and a migration guide in the &lt;a href="https://propzapi.com/blog/bannerbear-alternative/" rel="noopener noreferrer"&gt;full comparison&lt;/a&gt;. It's built on &lt;a href="https://propzapi.com" rel="noopener noreferrer"&gt;propzapi&lt;/a&gt;, a pay-as-you-go image generation API for developers and agents.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>saas</category>
      <category>productivity</category>
    </item>
    <item>
      <title>HTML to Image API: turn HTML and CSS into a PNG in one call</title>
      <dc:creator>Mukul Dutt</dc:creator>
      <pubDate>Thu, 06 Aug 2026 05:03:02 +0000</pubDate>
      <link>https://dev.to/paper_andbeyond/html-to-image-api-turn-html-and-css-into-a-png-in-one-call-1g2j</link>
      <guid>https://dev.to/paper_andbeyond/html-to-image-api-turn-html-and-css-into-a-png-in-one-call-1g2j</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://propzapi.com/blog/html-to-image-api/" rel="noopener noreferrer"&gt;propzapi.com&lt;/a&gt; — cross-posted here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You already wrote the layout. It's a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with some CSS, and it looks right in your browser. Now you need it as a PNG, a few hundred times, one per row in your database. That gap, between a page you can see and an image file you can host, is the whole job.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an HTML to image API actually does
&lt;/h2&gt;

&lt;p&gt;You POST HTML (or a stored template id plus data), it renders that markup in real headless Chromium, and hands back a hosted PNG/JPEG/WebP URL. No browser to install, no canvas library, no fonts to wrangle. Your CSS in, a picture out.&lt;/p&gt;

&lt;p&gt;The reason to reach for a service instead of a browser library like &lt;code&gt;html-to-image&lt;/code&gt; or &lt;code&gt;html2canvas&lt;/code&gt;: those run in the user's browser and taint the canvas the moment a cross-origin image or a webfont touches it, so the asset shows in the preview and then silently vanishes from the export. Server-side rendering sidesteps that entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just run Puppeteer yourself?
&lt;/h2&gt;

&lt;p&gt;You can. The script is an afternoon. Then production shows up: a single headless Chrome instance runs 300–500MB of RAM and climbs past 1GB over time, needs system fonts installed, and crashes under concurrency. On Lambda the full Chromium binary blows the 250MB package limit, so you're on &lt;code&gt;@sparticuz/chromium&lt;/code&gt; with a 2GB function and a bumped timeout. None of it is hard. It's just a browser you now operate, forever, to make pictures.&lt;/p&gt;

&lt;h2&gt;
  
  
  One call
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.propzapi.com/v1/images &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: pk_live_…"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"template":"og-article","data":{"title":"Ship an image for every row"},"format":"png"}'&lt;/span&gt;
&lt;span class="c"&gt;# → { "url": "https://images.propzapi.com/img_….png", "width":1200, "height":630, "bytes":95126 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store your own HTML once (with &lt;code&gt;{{variables}}&lt;/code&gt;), then render it per record. Because it's full Chromium, whatever CSS works in your browser works in the image — flexbox, grid, gradients, web fonts. Not a stripped-down subset of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  PNG, WebP or JPEG?
&lt;/h2&gt;

&lt;p&gt;PNG for text and sharp edges, since it's lossless. WebP when there's a photo or a gradient in the frame (about 26% smaller). JPEG only for mostly-photo art. Set &lt;code&gt;format&lt;/code&gt; and &lt;code&gt;scale&lt;/code&gt; (2 for retina) per call.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you don't need it
&lt;/h2&gt;

&lt;p&gt;If you have five fixed images that never change, make them by hand in Figma and move on. An API earns its place when the images are per-record and unbounded — a card per post, an invoice per order, a certificate per user.&lt;/p&gt;

&lt;p&gt;I wrote the full version — the self-host cost breakdown, a four-way comparison table, formats with real byte sizes, and the honest "when not to" — in the &lt;a href="https://propzapi.com/blog/html-to-image-api/" rel="noopener noreferrer"&gt;full HTML to Image API guide&lt;/a&gt;. It's built on &lt;a href="https://propzapi.com" rel="noopener noreferrer"&gt;propzapi&lt;/a&gt;, which also screenshots any URL, exports one-page PDFs, and ships an MCP server so an agent can render an image as a tool call.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
