Bisher stellte der Accessibility-Diagnosedienst von Liberogic Zertifikate und Berichte im HTML-Format bereit. Auf den Wunsch nach einem Zertifikat im PDF-Format haben wir nun reagiert: Ab sofort können wir Zertifikate und Berichte im PDF-Format ausstellen!
PDF-Zertifikat für die Web-Accessibility-Prüfung
PDF-Bericht zur Konformität mit Accessibility-Standards (VPAT / ACR)
Dafür haben wir ein System aufgebaut, das im Build-Prozess neben dem HTML automatisch auch PDF-Dateien erzeugt.
🛠️ Grundlage der PDF-Erstellung: Puppeteer und Umgebungsaufbau
Als PDF-Generierungswerkzeug haben wir Puppeteer eingesetzt, mit dem sich der Chromium-Browser im Headless-Modus steuern lässt. Da die HTML-Seiten bereits mit Astro erstellt werden, verlief die Einbindung von Puppeteer vergleichsweise reibungslos.
1. Sicherstellung der Rendering-Umgebung über einen lokalen Server
Puppeteer nutzt die Druckfunktion von Chromium. Lädt man jedoch lokale HTML-Dateien (file://) direkt, kann das Layout fehlerhaft dargestellt werden.
Um dies zu umgehen, wurde die folgende Umgebung aufgebaut.
- Temporärer Webserver: Startet einen temporären lokalen Webserver (
http-server) als Node.js-Kindprozess, der dasdist-Verzeichnis nach dem Build bereitstellt. - Stabile Umgebung: Indem Puppeteer über den Server auf
http://localhost:8080zugreift, wird eine stabile Rendering-Umgebung sichergestellt, die mit dem Browser identisch ist.
Code zum Aufbau der Umgebung und zum Start des Servers (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
Auf dem lokalen Server für die PDF-Erzeugung ist keine japanische Schriftart installiert, weshalb die in die PDF eingebetteten Schriften fehlerhaft dargestellt werden.
- Workaround für Schriftarten: Direkt vor der PDF-Erzeugung werden im Skript die Verweise auf Webfonts und die entsprechenden Stile dynamisch in das DOM eingefügt. Dadurch wird die PDF-Ausgabe mit japanischen Schriftarten möglich. Da das HTML aus Geschwindigkeitsgründen keine Webfonts verwendet, sorgt diese dynamische Einfügung dafür, dass nur das PDF betroffen ist.
Code für das dynamische Einfügen der Schriftarten (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-Referenzen von Links innerhalb der PDF
Am schwierigsten war das Problem mit den Links zwischen PDFs. Die in die PDF eingebetteten Links verwiesen auch nach der Bereitstellung weiterhin auf die lokale Entwicklungsumgebung (http://localhost:8080). Der Grund: Chromium behält die Basis-URI, die beim Laden des HTML verwendet wurde, als Ausgangspunkt für die PDF-Links bei.
Erzwungene Umwandlung der Links in absolute Pfade
Um dies zu lösen, haben wir die Links mit den folgenden Schritten nach der Bereitstellung zwangsweise in vollständige absolute Pfade umgeschrieben.
- Verwendung der Zieldomain: Die Domain der Bereitstellung (z. B.
https://example.com) wird aus der ProjektkonstanteSITE_URLabgerufen. - Erstellung und Ersetzung der absoluten 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 der abgerufenen Domain basiert (z. B.https://example.com/accessibility_report/pdf/acr-top.pdf). - Erneute Anwendung im DOM: Indem das umgeschriebene HTML erneut in Chromium angewendet wird (
page.setContent()), haben wir sichergestellt, dass die in das PDF eingebetteten Links fest auf die beabsichtigte Domain nach der Bereitstellung verweisen.
Code zur Linkumschreibung (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
});
🎉 Fazit
Da die Anforderung, Links zwischen PDFs zu setzen, etwas speziell war, hat es einige Mühe gekostet. Die Einführung von Puppeteer selbst verlief jedoch recht unkompliziert. Auch die Build-Zeiten sind kurz, und wir empfinden es als ein sehr nützliches Werkzeug!
Die wichtigsten Punkte bei dieser Umsetzung sind folgende:
- Sicherstellung der Stabilität durch Rendering über einen lokalen Server
- Japanische Unterstützung durch dynamische Einbindung von Webfonts
- Links zwischen PDFs durch absolute Pfade
Mit der PDF-Unterstützung hat sich der Nutzen unseres Services deutlich verbessert. Wir werden auch weiterhin daran arbeiten, die Qualität unseres Accessibility-Prüfservices zu steigern, der für Sie einen echten Mehrwert schafft.
Vom DTP in die Webwelt: Heute beherrscht er Markup, Frontend, Projektleitung und Barrierefreiheit gleichermaßen – ein wahrer "Techniker-Guru". Seit den Anfängen von Liberogic vielseitig im Einsatz und heute eine lebende Enzyklopädie im Team. Derzeit tüftelt er mit großer Begeisterung an effizienteren Abläufen durch gezielte Prompts – etwa mit der Frage: "Können wir bei der Barrierefreiheit nicht mehr auf KI setzen?" Technik und Denkweise entwickeln sich weiter.
Ayumu Futamata
IAAP-zertifizierter Web Accessibility Specialist (WAS) / Markup-Entwickler / Frontend-Entwickler / Webdirektor