Zurück zum Blog

web2pdf.eu: Webseite als PDF speichern – die Entwicklung einer mehrsprachigen PDF-Toolbox

web2pdf.eu: Webseite als PDF speichern – die Entwicklung einer mehrsprachigen PDF-Toolbox

Manche Projekte fangen mit einem Ärgernis an. Unseres begann mit dem Druckdialog des Browsers: Wer eine Webseite als PDF speichern will, bekommt dort ein Ergebnis, das mit der Seite auf dem Bildschirm oft wenig zu tun hat – abgeschnittene Spalten, fehlende Hintergründe, Cookie-Banner mitten im Layout, dazu ein Header und eine Fußzeile, die niemand haben wollte. Für ein Angebot, einen Rechnungsbeleg oder eine archivierte Produktseite ist das zu wenig. Aus diesem Ärgernis ist web2pdf.eu entstanden: erst ein einzelnes Werkzeug, inzwischen eine kleine PDF-Toolbox in 25 Sprachen.

Die Ausgangsidee: URL rein, PDF raus

Die erste Version im Dezember 2025 konnte genau eine Sache: Man fügt eine URL ein, drückt auf einen Knopf und bekommt ein PDF. Kein Konto, kein Wasserzeichen, keine Warteschlange. Diese Reduktion war eine bewusste Entscheidung – nicht, weil mehr technisch schwierig gewesen wäre, sondern weil jede zusätzliche Option den einen Anwendungsfall verwässert hätte, der die Leute überhaupt auf so eine Seite bringt.

Der entscheidende Qualitätsunterschied zum Druckdialog liegt darin, wie gerendert wird. Statt das Dokument durch die Druckvorschau zu schicken, lädt web2pdf.eu die Seite in einem echten Chromium und lässt sie vollständig ausführen: Webfonts, Bilder, CSS-Grid, Flexbox, alles. Erst danach entsteht das PDF. Was im PDF landet, ist deshalb das, was ein echter Besucher sehen würde – inklusive der Regeln aus @media print, wenn die Zielseite welche mitbringt.

Der Tech-Stack: SvelteKit, Puppeteer und ein Debian-Container

Für das Frontend fiel die Wahl auf SvelteKit, gebaut mit Vite und ausgeliefert über den Node-Adapter. Der Grund ist unspektakulär und genau deshalb richtig: Ein Werkzeug, das in erster Linie ein Eingabefeld und einen Knopf zeigt, soll klein bleiben und sofort da sein. Svelte kompiliert weg, was andere Frameworks zur Laufzeit mitschleppen – die Startseite kommt mit einem Bruchteil des JavaScripts aus, das eine vergleichbare React-Anwendung braucht. Wer die Abwägung im Detail nachlesen will, findet sie in unserem Framework-Vergleich zu Svelte.

Serverseitig übernimmt Puppeteer die Steuerung eines Headless-Chromium. Das klingt nach zwei Zeilen Code und war in der Praxis die größte Fehlerquelle des gesamten Projekts. Ein Auszug aus der Commit-Historie liest sich wie ein Lehrstück:

  • Falsche Fonts im Container: Das Debian-Image brachte anfangs keine Emoji- und keine Liberation-Schriften mit. Ergebnis: PDFs voller Ersatzkästchen. Behoben, indem fonts-noto-color-emoji und fonts-liberation fest ins Image wanderten.
  • System-Chromium gegen Puppeteer-Chrome: Das Debian-Chromium 150 stürzte in Kombination mit Puppeteer 24 reproduzierbar mit einem SIGTRAP ab. Die Lösung war, Puppeteer sein eigenes, versionsgleiches Chrome installieren zu lassen und die apt-Pakete nur noch als Lieferant der Shared Libraries zu nutzen.
  • Shared Memory: Chromium in Docker läuft ohne --disable-dev-shm-usage irgendwann in ein zu kleines /dev/shm und bricht mitten im Rendern ab. Ein Flag, ein Tag Fehlersuche.
Der Anwendungscode für „URL rein, PDF raus" umfasst ein paar Dutzend Zeilen. Der Container drumherum, der das Ganze zuverlässig macht, war die eigentliche Arbeit.

Wer selbst mit containerisierten Diensten arbeitet, findet die Grundlagen dazu in unserer Einführung in Docker und Container.

Von einem Werkzeug zu sechs

Nach dem Livegang zeigte die Suchkonsole schnell, wonach Leute wirklich suchten – und das war deutlich mehr als nur „Webseite als PDF". Nach und nach kamen fünf weitere Werkzeuge dazu, alle nach demselben Prinzip: eigene URL, eigener Titel, eine Aufgabe pro Seite.

  • Text aus PDF extrahieren: Zieht den Textinhalt aus einer PDF. Für gescannte Dokumente ohne Textebene springt OCRmyPDF mit Tesseract ein – mit Sprachpaketen für 24 europäische Sprachen im Image.
  • PDF zu HTML: Wandelt ein PDF in strukturiertes HTML um, etwa zur Weiterverarbeitung im Web oder im Newsletter.
  • HTML zu PDF: Eigenes HTML plus optionales CSS hochladen oder einfügen und daraus ein druckfertiges PDF rendern lassen. Das ist der Weg für alle, die Rechnungen, Zertifikate oder Serienbriefe aus Vorlagen erzeugen.
  • PDF zusammenfügen: Bis zu zehn Dateien in frei wählbarer Reihenfolge zu einem Dokument verbinden – umgesetzt mit pdfunite aus den Poppler-Utils.
  • PDF komprimieren: Drei Qualitätsstufen auf Basis von Ghostscript, mit Vorher-Nachher-Vergleich der Dateigröße. Der Klassiker für alle, deren Anhang am Mailserver-Limit scheitert.

Bemerkenswert an dieser Ausbaustufe: Sie kam ohne eine einzige neue Systemabhängigkeit aus. Ghostscript und die Poppler-Utils waren wegen der OCR-Kette ohnehin im Image. Zwei viel nachgefragte Funktionen entstanden damit fast ausschließlich aus Anwendungscode – ein gutes Argument dafür, den eigenen Container regelmäßig darauf abzuklopfen, was er eigentlich schon kann.

25 Sprachen – und warum sie zunächst unsichtbar blieben

web2pdf.eu ist von Anfang an in allen 25 Amtssprachen der EU verfügbar, von Bulgarisch über Luxemburgisch bis Schwedisch. Die Übersetzungen liegen als klassische PO-Kataloge vor und werden zur Bauzeit in kompilierte Module übersetzt – zur Laufzeit kostet die Mehrsprachigkeit dadurch praktisch nichts.

Der Fehler steckte woanders. Ursprünglich teilten sich alle 25 Sprachen eine einzige URL, die Sprachwahl lief über einen Query-Parameter und den Local Storage. Für Nutzer funktionierte das tadellos. Für Suchmaschinen existierten 24 dieser Sprachen schlicht nicht: Ein Parameter ist kein Sprachsignal, und ohne eigene URL gibt es nichts zu indexieren. Google beschreibt in seiner Dokumentation zu lokalisierten Versionen unmissverständlich, dass jede Sprachvariante eine eigene, verlinkbare URL braucht.

Die Korrektur bestand darin, echte Pfad-Präfixe einzuführen – /en/, /fr/, /pl/ und so weiter, mit Deutsch auf der Wurzel. Umgesetzt wurde das nicht durch Verschieben von Dateien, sondern über einen Reroute-Hook, der das Sprachpräfix abstreift, bevor das Routing greift. Dazu kamen hreflang-Annotationen für alle Varianten, ein x-default auf die englische Fassung und eine dynamisch erzeugte, mehrsprachige Sitemap. Aus einer indexierbaren Seite wurden über Nacht 150.

Der SEO-Relaunch: Was null Klicks bei vorhandenen Impressionen bedeuten

Der zweite große Umbau kam aus den Daten der Google Search Console. Das Muster war eindeutig und unangenehm: viele Impressionen, null Klicks. Die Seite tauchte in den Ergebnissen auf, wurde aber nicht angeklickt – bei markennahen Suchbegriffen sogar auf Position 10.

Die Ursachen waren fast durchweg hausgemacht: Die Meta-Description im Layout nannte versehentlich eine falsche Domain, die Seite /api-usage trug den Titel des Impressums, die Datenschutzseite hatte gar keine Beschreibung, und Open Graph, Canonicals sowie strukturierte Daten fehlten vollständig. Solche Fehler kosten keinen Ranking-Platz, aber jeden Klick.

Der Relaunch räumte auf: eine wiederverwendbare SEO-Komponente für alle Seiten, saubere Canonicals, Open-Graph- und Twitter-Card-Auszeichnung mit eigenem Share-Bild, dazu schema.org-Auszeichnung für Marke, Werkzeuge und FAQ. Parallel entstanden eigene Landingpages für die Cluster, die in den Daten sichtbar waren – etwa eine Seite für die PDF-API und ein Ratgeber zum Speichern von PDFs. Die Lehre daraus ist unbequem, aber allgemeingültig: Bevor man an Inhalten schraubt, sollte man prüfen, ob die vorhandenen überhaupt korrekt ausgezeichnet sind.

Sicherheit: Wenn Nutzer beliebiges HTML schicken dürfen

Ein Dienst, der fremde URLs lädt und fremdes HTML rendert, ist per Definition ein interessantes Ziel. Entsprechend viel Arbeit steckt in den Endpunkten:

  • Kein JavaScript beim HTML-zu-PDF-Rendern: Hochgeladenes HTML wird mit deaktiviertem JavaScript gerendert. Externe Ressourcen sind gesperrt – erlaubt sind ausschließlich data:-URIs und about:blank. Damit lässt sich der Dienst nicht als Proxy in fremde Netze missbrauchen.
  • Nur http und https: Die URL-Normalisierung ergänzt zwar fehlende Schemata, weist aber javascript:, data: und file: konsequent ab.
  • Ratenbegrenzung pro IP: Die rechenintensiven Endpunkte sind auf fünf Anfragen pro Stunde und zwanzig pro Tag begrenzt. Ein anfänglicher Bypass über den X-Forwarded-For-Header wurde behoben, indem der Wert des am weitesten rechts stehenden Hops ausgewertet wird statt des vom Client frei setzbaren ersten Eintrags.
  • Keine Fehlerdetails nach außen: Alle 500er-Antworten liefern generische Meldungen. Stacktraces und Pfadangaben bleiben im Log.
  • Ghostscript im Sandbox-Modus: Die Komprimierung läuft mit -dSAFER, Zeitlimits verhindern, dass eine präparierte Datei einen Prozess dauerhaft belegt.

Wer bei eigenen Projekten an derselben Stelle steht, findet die Grundlagen in unserem Beitrag zu den Grundlagen der Web-Sicherheit.

Datenschutz ist hier ein Produktmerkmal

Die Domain-Endung ist kein Zufall. Der Dienst läuft auf Servern innerhalb der EU, es gibt keine Nutzerkonten, kein Tracking und keine Weitergabe von Dokumenten an Dritte. Für alles, was mit personenbezogenen Daten in Berührung kommt – Verträge, Bewerbungen, Rechnungen, Behördenpost – ist das keine Marketingfloskel, sondern der Unterschied zwischen zulässig und rechtfertigungsbedürftig. Wer Dokumente über einen US-Dienst schickt, muss die Übermittlung nach Kapitel V der DSGVO begründen können. Wer sie in der EU verarbeitet, muss das nicht.

Wie sich dieser Anspruch praktisch auf Architekturentscheidungen auswirkt, haben wir in unserem Beitrag zu DSGVO-konformer Webentwicklung ausführlicher beschrieben. Die technische Gegenprobe – ob eine Website diese Anforderungen tatsächlich einhält – automatisiert unser Schwesterprojekt ScanCompliance.de.

Die Vorteile im Überblick

Wer sich fragt, warum man für „Seite als PDF" überhaupt ein eigenes Werkzeug braucht, findet die Antwort in dieser Liste:

  • Pixelgenaues Ergebnis: Die Seite wird vollständig gerendert – nicht durch die Druckvorschau gejagt. Layout, Schriften und Bilder bleiben erhalten.
  • Ohne Anmeldung und ohne Wasserzeichen: Keine Registrierung, keine Testphase, kein Logo quer über der ersten Seite.
  • Server in der EU: Verarbeitung im europäischen Rechtsraum, kein Tracking, keine Weitergabe.
  • Sechs Werkzeuge an einem Ort: Umwandeln, extrahieren, zusammenfügen und komprimieren – ohne für jeden Schritt einen anderen Anbieter zu suchen.
  • 25 Sprachen: Vollständig übersetzt, jede mit eigener URL.
  • Offene API: Jede Funktion der Oberfläche ist auch als HTTP-Endpunkt verfügbar.

Für Entwickler: die PDF-API

Was die Oberfläche kann, kann auch die Schnittstelle. Ein POST-Request mit Content-Type: application/json und der Ziel-URL im Body liefert direkt das fertige PDF als Binärantwort zurück – kein Polling, kein Job-Status, keine Callback-URL:

  • Methode: POST
  • URL: https://web2pdf.eu/api/generate-pdf
  • Body: { "url": "https://example.com" }
  • Antwort: application/pdf

Das reicht, um Angebots-PDFs aus einem Shop-Backend zu erzeugen, Landingpages für ein Archiv einzufrieren oder Reports aus einer internen Anwendung zu versenden. Für die anderen Werkzeuge existieren analoge Endpunkte. Wenn Sie so etwas in Ihre eigene Anwendung einbauen möchten, hilft unsere API-Integration weiter – und der Beitrag zu API-Best-Practices zeigt, worauf es beim Entwurf solcher Schnittstellen ankommt.

Was wir aus dem Projekt mitgenommen haben

Drei Dinge sind uns aus acht Monaten und gut hundert Commits im Gedächtnis geblieben.

Erstens: Bei Werkzeugen dieser Art liegt die Komplexität selten in der Fachlogik. Sie liegt in der Betriebsumgebung – in Schriften, Bibliotheksversionen, Speichergrenzen und Prozessisolierung. Wer den Aufwand für das Container-Image unterschätzt, unterschätzt das ganze Projekt.

Zweitens: Mehrsprachigkeit ohne URL-Strategie ist Arbeit, die niemand sieht. Vierundzwanzig hochwertige Übersetzungen waren monatelang für Suchmaschinen praktisch nicht vorhanden. Die Korrektur kostete einen Bruchteil der Zeit, die in die Übersetzungen geflossen war.

Drittens: Kleine, klar abgegrenzte Werkzeuge schlagen die große Suite. Jede Funktion hat eine eigene Seite mit eigenem Titel, eigener Beschreibung und genau einer Aufgabe. Das ist gut für Nutzer, die sofort verstehen, wo sie gelandet sind – und es ist gut für Suchmaschinen, die genau das bewerten können.

Wenn Sie ein ähnliches Werkzeug für Ihr Unternehmen brauchen – intern, als Kundenfunktion oder als API – dann ist das genau die Art von Projekt, die wir in der Webentwicklung umsetzen. Und wenn Sie einfach nur schnell eine Webseite als PDF speichern möchten: Dafür ist die Seite gebaut. Kostenlos, ohne Anmeldung, ohne Wasserzeichen.

web2pdf.eu: Webseite als PDF speichern – die Entwicklung einer mehrsprachigen PDF-Toolbox - Illustration 1web2pdf.eu: Webseite als PDF speichern – die Entwicklung einer mehrsprachigen PDF-Toolbox - Illustration 2

Lassen Sie uns Ihr Projekt gemeinsam umsetzen

Vereinbaren Sie ein kostenloses Erstgespräch – wir beraten Sie persönlich und unverbindlich.

Kostenloses Erstgespräch vereinbaren
Kostenloses Erstgespräch