Le service de diagnostic d'accessibilité de Liberogic fournissait jusqu'ici les certificats et rapports au format HTML. Suite aux demandes de nos clients souhaitant disposer des certificats au format PDF, nous proposons désormais de générer des certificats et des rapports au format PDF !
Certificat de vérification de l'accessibilité web au format PDF
Rapport de conformité à l'accessibilité au format PDF (VPAT / ACR)
Pour répondre à cette demande, nous avons mis en place un système qui génère automatiquement un PDF en parallèle de la sortie HTML lors du processus de build.
🛠️ Fondations de la génération PDF : Puppeteer et mise en place de l'environnement
Nous avons retenu Puppeteer comme outil de génération PDF, qui permet de piloter le navigateur Chromium en mode headless. Le site étant déjà construit avec Astro, l'intégration de Puppeteer s'est révélée relativement simple.
1. Mise en place d'un environnement de rendu via un serveur local
Puppeteer utilise la fonction d'impression de Chromium, mais lorsqu'un fichier HTML local (file://) est chargé directement, la mise en page peut se dérégler.
Pour contourner ce problème, nous avons mis en place l'environnement suivant.
- Serveur web temporaire : après la compilation, un serveur web local temporaire (
http-server) hébergeant le répertoiredistest lancé comme processus enfant de Node.js. - Environnement stable : en faisant accéder Puppeteer au site via le serveur (
http://localhost:8080), nous avons assuré un rendu identique à celui du navigateur.
Extrait du code de configuration de l'environnement et de démarrage du serveur
// プロジェクト定数からドメインを取得し、未設定なら 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. Application de la police japonaise
L'environnement de serveur local utilisé pour la génération de PDF ne disposant d'aucune police japonaise, les polices intégrées au PDF s'affichent incorrectement.
- Contournement de la police : juste avant la génération du PDF, le script insère dynamiquement dans le DOM la référence à une police web et les styles correspondants. Cela permet d'obtenir un PDF avec la police japonaise. Comme la version HTML n'utilise pas de police web afin de privilégier la vitesse, cette insertion dynamique ne s'applique qu'au PDF.
Extrait du code d'insertion dynamique de la police
// 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);
🚨 Principal défi : problème de référence d'URL dans les liens du PDF
Le point le plus difficile concernait les liens entre PDF. Les liens intégrés au PDF continuaient de pointer vers l'URL de l'environnement de développement local (http://localhost:8080) même après le déploiement. Ce phénomène se produit parce que Chromium conserve l'URI de base du HTML chargé comme point de référence pour les liens du PDF.
Forcer la conversion des liens en chemins absolus
Pour résoudre ce problème, nous avons réécrit les liens en chemins absolus complets une fois déployés, selon la procédure suivante.
- Utilisation du domaine de déploiement : le domaine de déploiement (par exemple
https://example.com) est récupéré à partir de la constante du projetSITE_URL. - Construction et remplacement des URL absolues : avec Node.js, nous récupérons le contenu HTML et réécrivons le lien d'origine (
/accessibility_report/top/) en une URL complète basée sur le domaine récupéré (par exemplehttps://example.com/accessibility_report/pdf/acr-top.pdf). - Réapplication au DOM : en réinjectant le HTML réécrit dans Chromium via
page.setContent(), nous avons garanti que les liens intégrés au PDF pointent de manière fixe vers le domaine de déploiement prévu.
Extrait du code de réécriture des liens
// 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
});
🎉 En résumé
Cette tâche a été un peu délicate, car elle impliquait de créer des liens entre des PDF, une exigence particulière. En revanche, la mise en place de Puppeteer a été assez simple. Le temps de build est court, et nous trouvons cet outil très pratique !
Les points clés de cette intervention sont les suivants :
- Garantir la stabilité grâce au rendu via un serveur local
- Prise en charge du japonais grâce à l'injection dynamique de polices web
- Liens entre PDF grâce à la conversion des liens en chemins absolus
La prise en charge du PDF améliore nettement la praticité de notre service. Nous continuerons à nous efforcer d'offrir un service de diagnostic d'accessibilité toujours plus précieux pour nos clients !
Passé du DTP au Web, il maîtrise aussi bien le balisage que le frontend, la direction de projet et l'accessibilité : un véritable « sage de la technique ». Actif chez Liberogic depuis ses débuts, il est aujourd'hui une référence interne incontournable. Ces derniers temps, il explore avec passion l'optimisation par l'IA : « Ne pourrait-on pas davantage s'appuyer sur l'IA pour l'accessibilité ? » Sa technique comme sa réflexion continuent d'évoluer.
Ayumu Futamata
Spécialiste certifié en accessibilité web IAAP (WAS) / Intégrateur balisage / Ingénieur frontend / Directeur web