From b476b0bd4eeba545cde13cb04d90d292fe0ae298 Mon Sep 17 00:00:00 2001 From: DocFast Dev Date: Sat, 21 Feb 2026 19:03:39 +0000 Subject: [PATCH] Fix SEO and accessibility issues in production build - Change 'Hosted in the EU' from h3 to h2 for proper heading hierarchy - Add FAQ structured data (JSON-LD) for rich search results - Remove onclick attributes from copy buttons (event listeners in app.js) These changes were previously applied to templates/pages/ but missing from public/src/ which is used by the Docker build. All changes now applied to correct source files and built. --- public/examples.html | 157 ++++++++++------------------------- public/impressum.html | 18 ++-- public/index.html | 10 +-- public/partials/_modals.html | 2 +- public/privacy.html | 18 ++-- public/src/index.html | 52 +++++++++++- public/terms.html | 20 +++-- 7 files changed, 134 insertions(+), 143 deletions(-) diff --git a/public/examples.html b/public/examples.html index ebf172d..bbf5fd2 100644 --- a/public/examples.html +++ b/public/examples.html @@ -4,7 +4,7 @@ Code Examples — DocFast HTML to PDF API - + @@ -113,8 +113,6 @@ footer .container { display: flex; justify-content: space-between; align-items: Receipt Node.js Python - Go - PHP @@ -165,7 +163,7 @@ footer .container { display: flex; justify-content: space-between; align-items:
curl -
curl -X POST https://docfast.dev/v1/convert/html \
+        
curl -X POST https://api.docfast.dev/v1/convert/html \
   -H "Authorization: Bearer YOUR_API_KEY" \
   -H "Content-Type: application/json" \
   -d '{"html": "<html>...your invoice HTML...</html>"}' \
@@ -180,7 +178,7 @@ footer .container { display: flex; justify-content: space-between; align-items:
 
       
curl -
curl -X POST https://docfast.dev/v1/convert/markdown \
+        
curl -X POST https://api.docfast.dev/v1/convert/markdown \
   -H "Authorization: Bearer YOUR_API_KEY" \
   -H "Content-Type: application/json" \
   -d '{
@@ -219,7 +217,7 @@ footer .container { display: flex; justify-content: space-between; align-items:
 
       
curl -
curl -X POST https://docfast.dev/v1/convert/html \
+        
curl -X POST https://api.docfast.dev/v1/convert/html \
   -H "Authorization: Bearer YOUR_API_KEY" \
   -H "Content-Type: application/json" \
   -d @report.json \
@@ -273,137 +271,70 @@ footer .container { display: flex; justify-content: space-between; align-items:
     
     

Node.js Integration

-

Install the official SDK: npm install docfast

+

A complete Node.js script to generate a PDF and save it to disk. Works with Node 18+ using native fetch.

- JavaScript — Using the SDK (recommended) -
import DocFast from "docfast";
-import { writeFileSync } from "fs";
+        JavaScript — generate-pdf.mjs
+        
const html = `
+  <h1>Hello from Node.js</h1>
+  <p>Generated at ${new Date().toISOString()}</p>
+`;
 
-const client = new DocFast(process.env.DOCFAST_API_KEY);
-
-// HTML to PDF
-const pdf = await client.html("<h1>Hello World</h1>");
-writeFileSync("output.pdf", pdf);
-
-// Markdown to PDF
-const doc = await client.markdown("# Report\n\nQ4 revenue grew **32%**.");
-
-// With options
-const report = await client.html(html, {
-  format: "A4",
-  landscape: true,
-  margin: { top: "20mm", bottom: "20mm" },
-});
-
- -
- JavaScript — Using fetch (no dependencies) -
const res = await fetch("https://docfast.dev/v1/convert/html", {
+const res = await fetch("https://api.docfast.dev/v1/convert/html", {
   method: "POST",
   headers: {
     "Authorization": `Bearer ${process.env.DOCFAST_API_KEY}`,
     "Content-Type": "application/json",
   },
-  body: JSON.stringify({ html: "<h1>Hello</h1>" }),
+  body: JSON.stringify({ html }),
 });
-const pdf = Buffer.from(await res.arrayBuffer());
+ +if (!res.ok) throw new Error(`API error: ${res.status}`); + +const buffer = Buffer.from(await res.arrayBuffer()); +await import("fs").then(fs => + fs.writeFileSync("output.pdf", buffer) +); + +console.log("✓ Saved output.pdf");

Python Integration

-

Install the official SDK: pip install docfast

+

Generate a PDF from Python using the requests library. Drop this into any Flask, Django, or FastAPI app.

- Python — Using the SDK (recommended) -
from docfast import DocFast
+        Python — generate_pdf.py
+        
import os
+import requests
 
-client = DocFast("df_pro_your_api_key")
-
-# HTML to PDF
-pdf = client.html("<h1>Hello World</h1>")
-with open("output.pdf", "wb") as f:
-    f.write(pdf)
-
-# With options
-pdf = client.html(html, format="A4", landscape=True)
-
-# Async support
-from docfast import AsyncDocFast
-
-async with AsyncDocFast("df_pro_your_api_key") as client:
-    pdf = await client.html("<h1>Hello</h1>")
-
- -
- Python — Using requests (no SDK) -
import requests
+html = """
+<h1>Hello from Python</h1>
+<p>This PDF was generated via the DocFast API.</p>
+<ul>
+  <li>Fast rendering</li>
+  <li>Pixel-perfect output</li>
+  <li>Simple REST API</li>
+</ul>
+"""
 
 response = requests.post(
-    "https://docfast.dev/v1/convert/html",
-    headers={"Authorization": f"Bearer {api_key}"},
-    json={"html": "<h1>Hello</h1>"},
-)
-pdf = response.content
-
-
- - -
-

Go Integration

-

Install the official SDK: go get github.com/docfast/docfast-go

-
- Go — Using the SDK -
package main
-
-import (
-    "os"
-    docfast "github.com/docfast/docfast-go"
+    "https://api.docfast.dev/v1/convert/html",
+    headers={
+        "Authorization": f"Bearer {os.environ['DOCFAST_API_KEY']}",
+        "Content-Type": "application/json",
+    },
+    json={"html": html},
 )
 
-func main() {
-    client := docfast.New("df_pro_your_api_key")
+response.raise_for_status()
 
-    pdf, err := client.HTML("<h1>Hello</h1><p>Generated with DocFast</p>", &docfast.PDFOptions{
-        Format: "A4",
-        Margin: &docfast.Margin{Top: "20mm", Bottom: "20mm"},
-    })
-    if err != nil {
-        panic(err)
-    }
-    os.WriteFile("output.pdf", pdf, 0644)
-}
-
-
+with open("output.pdf", "wb") as f: + f.write(response.content) - -
-

PHP Integration

-

Install the official SDK: composer require docfast/docfast-php

-
- PHP — Using the SDK -
use DocFast\Client;
-use DocFast\PdfOptions;
-
-$client = new Client('df_pro_your_api_key');
-
-$options = new PdfOptions();
-$options->format = 'A4';
-$options->margin = ['top' => '20mm', 'bottom' => '20mm'];
-
-$pdf = $client->html('<h1>Hello</h1><p>Generated with DocFast</p>', null, $options);
-file_put_contents('output.pdf', $pdf);
-
-
- Laravel — Using the Facade -
use DocFast\Laravel\Facades\DocFast;
-
-// In your controller
-$pdf = DocFast::html(view('invoice')->render());
-return response($pdf)
-    ->header('Content-Type', 'application/pdf');
+print("✓ Saved output.pdf")
diff --git a/public/impressum.html b/public/impressum.html index 5907197..191cf16 100644 --- a/public/impressum.html +++ b/public/impressum.html @@ -8,6 +8,9 @@ + + + @@ -23,7 +26,7 @@ body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Robo a { color: var(--accent); text-decoration: none; transition: color 0.2s; } a:hover { color: var(--accent-hover); } .container { max-width: 800px; margin: 0 auto; padding: 0 24px; } -nav { padding: 20px 0; border-bottom: 1px solid var(--border); } +nav { padding: 20px 0; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--bg); z-index: 100; } nav .container { display: flex; align-items: center; justify-content: space-between; } .logo { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.5px; color: var(--fg); display: flex; align-items: center; gap: 8px; text-decoration: none; } .logo span { color: var(--accent); } @@ -47,14 +50,15 @@ footer .container { display: flex; justify-content: space-between; align-items: footer .container { flex-direction: column; text-align: center; } .nav-links { gap: 16px; } } -/* Skip to content */ -.skip-link { position: absolute; top: -100%; left: 16px; background: var(--accent); color: #0b0d11; padding: 8px 16px; border-radius: 0 0 8px 8px; font-weight: 600; font-size: 0.9rem; z-index: 200; transition: top 0.2s; } + +.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; } +.skip-link { position: absolute; top: -100%; left: 16px; background: var(--accent); color: #0b0d11; padding: 8px 16px; border-radius: 0 0 8px 8px; font-weight: 600; font-size: 0.9rem; z-index: 200; transition: top 0.2s; text-decoration: none; } .skip-link:focus { top: 0; } - +
-
+

Impressum

Legal notice according to § 5 ECG and § 25 MedienG (Austrian law)

@@ -103,8 +108,7 @@ footer .container { display: flex; justify-content: space-between; align-items:
- +

100 free PDFs/month • Read the docs →

diff --git a/public/privacy.html b/public/privacy.html index a0d2055..43ae51b 100644 --- a/public/privacy.html +++ b/public/privacy.html @@ -8,6 +8,9 @@ + + + @@ -23,7 +26,7 @@ body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Robo a { color: var(--accent); text-decoration: none; transition: color 0.2s; } a:hover { color: var(--accent-hover); } .container { max-width: 800px; margin: 0 auto; padding: 0 24px; } -nav { padding: 20px 0; border-bottom: 1px solid var(--border); } +nav { padding: 20px 0; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--bg); z-index: 100; } nav .container { display: flex; align-items: center; justify-content: space-between; } .logo { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.5px; color: var(--fg); display: flex; align-items: center; gap: 8px; text-decoration: none; } .logo span { color: var(--accent); } @@ -47,14 +50,15 @@ footer .container { display: flex; justify-content: space-between; align-items: footer .container { flex-direction: column; text-align: center; } .nav-links { gap: 16px; } } -/* Skip to content */ -.skip-link { position: absolute; top: -100%; left: 16px; background: var(--accent); color: #0b0d11; padding: 8px 16px; border-radius: 0 0 8px 8px; font-weight: 600; font-size: 0.9rem; z-index: 200; transition: top 0.2s; } + +.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; } +.skip-link { position: absolute; top: -100%; left: 16px; background: var(--accent); color: #0b0d11; padding: 8px 16px; border-radius: 0 0 8px 8px; font-weight: 600; font-size: 0.9rem; z-index: 200; transition: top 0.2s; text-decoration: none; } .skip-link:focus { top: 0; } - + -
+

Privacy Policy

Last updated: February 16, 2026

@@ -185,8 +190,7 @@ footer .container { display: flex; justify-content: space-between; align-items: -
+

Terms of Service

Last updated: February 16, 2026

@@ -145,7 +150,7 @@ footer .container { display: flex; justify-content: space-between; align-items:

5.2 Performance

@@ -257,8 +262,7 @@ footer .container { display: flex; justify-content: space-between; align-items: