Der Accessibility-Audit-Service von Liberogic bot Zertifikate und Berichte bisher im HTML-Format an. Auf Wunsch unserer Kunden bieten wir nun auch Zertifikate und Berichte im PDF-Format an!
PDF-Compliance-Prüfbericht für Webzugänglichkeit
PDF-Konformitätsbericht für Accessibility (VPAT / ACR)
Für diese Umsetzung haben wir ein System entwickelt, das gleichzeitig mit der HTML-Ausgabe im Build-Prozess automatisch PDFs generiert.
🛠️ Infrastruktur für die PDF-Generierung: Puppeteer und Umgebungskonfiguration
Wir nutzen Puppeteer, ein Tool zur headless-Steuerung von Chromium, zur PDF-Generierung. Da das HTML bereits mit Astro aufgebaut ist, war die Integration von Puppeteer relativ reibungslos.
1. Sicherung der Rendering-Umgebung durch lokalen Server
Puppeteer nutzt die Druckfunktion von Chromium. Wenn man lokale HTML-Dateien (file://) direkt lädt, tritt ein Layout-Fehler auf.
Um dies zu vermeiden, habe ich die folgende Umgebung aufgebaut.
- Temporärer Webserver: Nach dem Build wird das
dist-Verzeichnis von einem temporären lokalen Webserver (http-server) gehostet, der als untergeordneter Prozess von Node.js gestartet wird. - Stabile Umgebung: Durch den Zugriff von Puppeteer über den Server (
http://localhost:8080) wird eine stabile Rendering-Umgebung gewährleistet, die mit der des Browsers identisch ist.
Code für Umgebungsaufbau und Serverstart (Auszug)
// プロジェクト定数からドメインを取得し、未設定なら localhost:8080 を使用
const HOST_DOMAIN = SITE_URL || `http://localhost:${PORT}`;
const BUILD_ROOT = path.join(__dirname, 'dist');
const PORT = 8080;
// --- サーバーの起動ロジック ---
let serverProcess = exec(`npx http-server ${BUILD_ROOT} -p ${PORT} -s --silent`);
// サーバーが起動するまで待機
await new Promise((resolve) => setTimeout(resolve, 2000));
// --- Puppeteerのページアクセス ---
// Puppeteerは localhost:8080 にアクセスし、レンダリングを開始します
const serverUrl = `http://localhost:${PORT}/${REPORT_DIR}/${urlPath}`;
await page.goto(serverUrl, { waitUntil: 'networkidle0' });
2. Anwendung japanischer Schriftarten
Die lokale Serverumgebung für die PDF-Erstellung verfügt nicht über japanische Schriftarten, was dazu führt, dass die in das PDF eingebetteten Schriftarten fehlerhaft angezeigt werden.
- Schriftarten-Workaround: Das Skript fügt unmittelbar vor der PDF-Erstellung Webfont-Verweise und Anwendungsstile dynamisch in das DOM ein. Dies ermöglicht die PDF-Ausgabe mit japanischen Schriftarten. Da die HTML-Seite aus Leistungsgründen keine Webfonts verwendet, wird durch diese dynamische Einfügung sichergestellt, dass die Schriftarten nur beim PDF angewendet werden.
Code für dynamische Schriftarten-Einfügung (Auszug)
// Webフォントの動的挿入ロジック (page.evaluateでブラウザ側で実行)
await page.evaluate((fontUrl) => {
// <link>タグを生成してDOMに挿入
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = fontUrl;
document.head.appendChild(link);
// @media print スタイルを強制的に挿入し、フォントを適用
const printStyle = document.createElement('style');
printStyle.textContent = `
@media print {
html, body {
font-family: 'Noto Sans JP', sans-serif !important;
}
}
`;
document.head.appendChild(printStyle);
}, WEBFONTS_URL);
🚨 Größte Herausforderung: URL-Referenzierungsproblem bei Links im PDF
Das größte Problem war die Verlinkung zwischen PDFs. Links, die im PDF eingebettet sind, verweisen nach dem Deployment immer noch auf die lokale Entwicklungsumgebungs-URL (http://localhost:8080). Dies geschieht, weil Chromium die Basis-URI beibehält, die beim Laden der HTML-Datei vorhanden war, als Ausgangspunkt für PDF-Links.
Erzwungene absolute Pfade für Links
Um dieses Problem zu beheben, haben wir die Links in den folgenden Schritten dazu gezwungen, nach der Bereitstellung mit vollständigen absoluten Pfaden umgeschrieben zu werden.
- Verwendung der Bereitstellungsdomäne: Die Bereitstellungsdomäne (z. B.
https://example.com) wird aus der Projektkonstante (SITE_URL) abgerufen. - Konstruktion und Ersetzung absoluter URLs: Mit Node.js wird der HTML-Inhalt abgerufen und der ursprüngliche Link (
/accessibility_report/top/) durch eine vollständige URL ersetzt, die auf die abgerufene Domäne basiert (z. B.https://example.com/accessibility_report/pdf/acr-top.pdf). - Erneute Anwendung auf das DOM: Der umgeschriebene HTML-Code wird auf Chromium angewandt (
page.setContent()), wodurch die in das PDF eingebetteten Links auf die beabsichtigte bereitgestellte Domäne festgelegt werden.
Code für das Umschreiben von Links (Auszug)
// 1. 無効化したいリンク(.link-ignore-pdf)を物理的に削除
const ignoreLinkRegex = new RegExp(`(<a\\\\s+[^>]*class=["'][^"']*${ignoreClass}[^"']*["'][^>]*>)(.*?)(<\\/a\\\\s*>)`, 'gi');
content = content.replace(ignoreLinkRegex, '$2'); // <a>タグ全体を中身のテキストに置換
// 2. 詳細ページへのリンクを絶対URLに書き換え
const detailLinkRegex = new RegExp(`href="${reportDirRootLink}([^/]+)\\/"`, 'g');
const detailPdfUrl = `${pdfAbsoluteUrl}/acr-top.pdf`; // 例
content = content.replace(detailLinkRegex, (match, slug) => {
// リンクを <http://localhost>... ではなく、<https://example.com/>... に強制置換
return `href="${pdfAbsoluteUrl}/acr-${slug}.pdf"`;
});
// 3. 最終的なコンテンツをブラウザに再適用し、PDF出力へ
await page.setContent(content, {
waitUntil: 'domcontentloaded',
baseURL: baseUrlForContent
});
🎉 Zusammenfassung
Diese Anforderung, Links zwischen PDFs zu verknüpfen, war etwas ungewöhnlich und bereitete einige Schwierigkeiten, aber die Implementierung von Puppeteer selbst verlief relativ problemlos. Der Build ist schnell und es ist wirklich ein praktisches Tool!
Die Schlüsselpunkte dieser Implementierung sind:
- Sicherung der Stabilität durch Rendering über einen lokalen Server
- Dynamische Webfont-Injektion für japanische Zeichenunterstützung
- Absolute Pfadifizierung von Links zwischen PDF-Dokumenten
Mit der PDF-Unterstützung hat sich die Benutzerfreundlichkeit unseres Service erheblich verbessert. Wir werden auch weiterhin die Qualität unseres Accessibility-Audit-Service zu einem Mehrwert für unsere Kunden verfolgen!
Von DTP in die Web-Welt – und dann Markup, Frontend, Projektleitung und Accessibility alles gemeistert: ein "Technik-Weise". Seit den Anfangstagen von Liberogic vielseitig tätig und mittlerweile eine lebende Wissensquelle im Unternehmen. Derzeit fasziniert von der Frage "Können wir Accessibility-Umsetzung noch stärker mit KI unterstützen?" und erforscht Optimierungsmöglichkeiten durch gezieltes Prompt-Engineering. Technisch wie gedanklich immer noch in Entwicklung.
Futa
IAAP-zertifizierter Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director