Skip to main content

From `@sample-sdk` to Production: Launching Html2Pdf for 21 Indian Languages

Updated 5 min readMarkdown

In my first post, I shared why I started building an HTML-to-PDF converter after hitting repeated PDF rendering headaches in my AI Question Generator project. Back then, the tool wasn't released yet—my code snippet still used a placeholder package called @sample-sdk/html2pdf-sdk.

Today, the placeholder is gone. Html2Pdf is officially live in production:

In that first post, I set three goals for the tool: Multilingual, Fast, and Trustworthy. Here is how those three promises turned into a real product you can use today.

1. Multilingual: 21 Indian Languages Across 12 Scripts (No More Tofu Boxes)

If you have ever tried generating a Hindi, Tamil, or Bengali PDF inside a standard Linux Docker container, you have probably seen empty rectangles (□□□—"tofu") or broken vowel signs instead of text. Most lightweight PDF libraries don't shape complex Indic ligatures properly, and minimal cloud containers don't ship with Indian language fonts.

Html2Pdf runs headless Chromium inside an isolated container pre-bundled with Google Noto typography and a custom fonts.conf pipeline. Before the engine captures the PDF, it waits for document.fonts.ready so every glyph renders cleanly.

Out of the box, it supports 21 Indian languages across 12 scripts with zero font setup on your end:

Script Supported Languages
Devanagari Hindi, Marathi, Nepali, Sanskrit
Bengali Bengali, Assamese
Gurmukhi Punjabi
Gujarati Gujarati
Odia Odia
Tamil Tamil
Telugu Telugu
Kannada Kannada
Malayalam Malayalam
Ol Chiki Santali
Meetei Mayek Manipuri
Nastaliq Urdu

You can test all 21 language scripts right now using the interactive preview cards on html2pdf.akcraft.app without even creating an account.

2. Fast & Ergonomic: The Real @akcraft/html2pdf-sdk

In my first post, I showed the rough API idea. Now you can install the real zero-dependency TypeScript SDK directly from npm:

npm install @akcraft/html2pdf-sdk

The client points to https://api.html2pdf.akcraft.app by default, ships with full TypeScript types for paper formats (A0–A6, Letter, Legal, Tabloid, Ledger) and page orientation (portrait, landscape), and surfaces structured errors (Html2PdfError with statusCode, apiError, and retryAfter).

import {
  Html2PdfClient,
  PaperFormat,
  PdfOrientation,
  Html2PdfError,
} from "@akcraft/html2pdf-sdk";

const client = new Html2PdfClient(process.env.HTML2PDF_API_KEY);

try {
  const result = await client.sendHtmlRequest({
    userId: "YOUR_USER_ID",
    content: "<h1>नमस्ते दुनिया</h1><p>Generated with @akcraft/html2pdf-sdk</p>",
    options: {
      format: PaperFormat.A4,
      orientation: PdfOrientation.Portrait,
    },
  });

  console.log(result.jobId);    // Unique conversion job ID
  console.log(result.status);   // "completed"
  console.log(result.pdfUrl);   // Presigned download URL (valid for 1 hour)
  console.log(result.fileName); // Stored PDF filename
} catch (err) {
  if (err instanceof Html2PdfError) {
    console.error(`API Error (${err.statusCode}): ${err.apiError}`);
    if (err.retryAfter) {
      console.error(`Rate limit reached. Retry after ${err.retryAfter}s`);
    }
  }
}

Prefer plain HTTP or another language? You can call POST https://api.html2pdf.akcraft.app/api/send-html directly with an x-api-key header from Python, Go, cURL, or any backend.

3. Trustworthy: Built-In Key Security & Self-Cleaning Storage

When you send HTML templates—whether invoices, exam papers, or reports—you shouldn't have to worry about leaked API keys or sensitive PDFs sitting in a public bucket forever. Here is how Html2Pdf protects your account and files:

  • One-Time SHA-256 Hashed API Keys: When you generate an API key (h2p_live_...) in the dashboard, it is generated client-side via crypto.getRandomValues and shown to you once. Our database stores only its SHA-256 hash—never plaintext—and supports instant soft-revocation.

  • Presigned URLs & 2-Hour Auto-Deletion: Every converted PDF returns a presigned download link that expires in 1 hour, and you can manually delete any file immediately from your dashboard or via DELETE /api/delete-file/:fileName. On the backend, an automated cleanup job that sweeps storage every 15 minutes to purge files older than 2 hours is currently in beta testing—so if you need immediate removal, use manual deletion anytime.

  • Beta Version Limits: For the beta, I've kept limits generous at 10 conversions/minute and 1,000,000 conversions/month, with automatic quota rollback if a render or storage upload ever fails.

A Quick Look at the Developer Dashboard

At html2pdf.akcraft.app/dashboard (with Email/Password or Google OAuth sign-in), you get three focused views to manage your integration:

  • Overview: Track your conversion counts, monthly quota usage, and active key snippet at a glance.

  • API Keys: Create new h2p_live_... keys with a reveal-once modal and revoke old keys without breaking historical job logs.

  • History: Browse paginated conversion logs, download active PDFs, or delete files on demand.

Before launching, I locked the codebase behind a 116-test automated gate (53 Fastify API tests, 40 Astro/React website tests, and 23 Vitest SDK tests) with zero failing tests.

Try It Out & What's Coming Next in This Series

You can try the live HTML-to-PDF previewer right now at html2pdf.akcraft.app or grab @akcraft/html2pdf-sdk) on npm.

Because a lot went into building the backend, I'm splitting the technical deep dives into upcoming posts:

  1. How I Solved the Indic Font "Tofu" Problem in Dockerized Headless Chromium (bundling 21 Indian languages across 12 scripts with Fastify 5 and Puppeteer).

  2. Designing Dual-Gate Rate Limiting, Atomic S3 Rollbacks & SHA-256 API Keys (using Upstash Redis Lua scripts, Supabase, and Astro 7 SSR proxies).

Let me know in the comments which deep dive you'd like to read first—and if you test the SDK in your own project, I'd love your feedback!

#javascript #typescript #pdf #buildinpublic #npm #webdev

No comments yet. Be the first to comment.