# From fragile iframes to server-side PDFs: a rendering migration story with Playwright

> Source: <https://dev.to/benmallessamohamedamine/from-fragile-iframes-to-server-side-pdfs-a-rendering-migration-story-with-playwright-hhl>
> Published: 2026-07-04 01:07:09+00:00

**By Mohamed Amine Ben Mallessa — Lead Dev at Sollea AI**

The application we shipped generates customized posters from a simple web form. Users fill in their event details (dates, venue, times) and the app produces a print-ready document.

Tech stack: **Next.js 15** (App Router, TypeScript, TanStack Query) + **FastAPI** (SQLAlchemy 2, PostgreSQL). Modern stack — but document rendering was the weak link.

When we started, Photopea looked ideal: a free Photoshop clone, scriptable via JavaScript. In production, it turned into a maintenance sink:

PSD files had to be publicly hosted with `Access-Control-Allow-Origin: *`

. A CORS requirement that the client's infrastructure couldn't meet.

Exports traveled through a backend API route (`/photopea/exports`

). Network latency or timeouts could silently truncate exports.

Everything went through the client's browser. No automated generation, no CI/CD pipeline.

When a poster had rendering issues, nobody could tell if the problem was Photopea, the network, the PSD, or the code.

Instead of a closed PSD, each poster format is an open HTML file versioned in the repo. Full control of layout, CSS, SVG.

Headless Chromium via Playwright produces a perfect vector PDF and high-res PNG. Average time: 3.5 seconds per poster. Fully reproducible.

The same HTML template serves both the live iframe preview AND the Playwright final render. **Zero difference between preview and printed document.**

| Metric | Before (Photopea) | After (HTML Engine) |
|---|---|---|
| External dependencies | 2 (Canva, Photopea) | 1 (Playwright) |
| License cost | $$$$ (Canva Enterprise) | $0 |
| Render time | 30-60s (network dependent) | ~3.5s |
| Server-side render | Impossible | PDF + PNG |
| Reliability | Fragile | Robust |
| Adding a template | Complex config | One folder + manifest |

"Free" solutions with complex infrastructure often end up costing more than a simple solution you fully control.

An HTML template isn't as powerful as a PSD — but it has three decisive advantages: **it's readable, versionable, and reproducible.**

Thanks to **Nassim Tarkhani** for pushing this direction. This idea saved the project.

**Mohamed Amine Ben Mallessa** — Lead Dev at Sollea AI

🔗 [GitHub](https://github.com/mohamed-amine-ben-mallessa) | [LinkedIn](https://fr.linkedin.com/in/benmallessa)

*Need help with your technical stack? Sollea AI specializes in custom automation and AI solutions.*

**Sollea AI** — Full-stack development, AI automation, custom solutions.

🔗 ** Sollea AI** ·

*Team led by **Mohamed Amine Ben Mallessa** — Lead Dev at Sollea AI*
