QR Codes
Generate and embed QR codes in your PDFs automatically
Automatically generate QR codes during PDF creation using inline data attributes. Perfect for certificates, tickets, invoices, and product labels - no separate API calls needed!
Quick Start
Embed QR codes directly in your HTML using the data-qr attribute:
<!DOCTYPE html>
<html>
<body style="font-family: Arial; text-align: center; padding: 40px;">
<h1>Certificate of Completion</h1>
<p>Awarded to: John Doe</p>
<div style="margin-top: 40px;">
<p>Scan to verify:</p>
<img data-qr="https://syntaxdoc.com/verify/cert-12345"
data-qr-size="200"
alt="Verification QR Code" />
</div>
</body>
</html>That's it! When you generate the PDF, SyntaxDoc automatically:
- Detects all
data-qrattributes - Generates QR codes
- Embeds them as data URLs
- Renders them in the final PDF
No separate API calls, no manual QR generation - just add data-qr to any <img> tag and it works automatically!
How It Works
During PDF generation, SyntaxDoc preprocesses your HTML to find all <img> tags with data-qr attributes, generates the corresponding QR codes, and replaces them with actual image data before rendering.
Before Processing:
<img data-qr="https://example.com/verify/123" data-qr-size="180" />After Processing (automatic):
<img src="data:image/png;base64,iVBORw0KGgo..." width="180" height="180" />Data Attributes
Control QR code generation using HTML data attributes:
| Attribute | Type | Default | Description |
|---|---|---|---|
data-qr | string | Required | URL or text to encode |
data-qr-size | number | 200 | QR code size in pixels |
data-qr-margin | number | 1 | White margin around QR code (0-10) |
data-qr-error-correction | string | "M" | Error correction: L, M, Q, H |
data-qr-dark-color | string | "#000000" | Dark modules color (hex format only) |
data-qr-light-color | string | "#ffffff" | Light modules color (hex format only) |
Colors must be in hex format (#RRGGBB). RGB/RGBA formats are not supported and will fall back to defaults.
Example with all options:
<img data-qr="https://example.com/verify/123"
data-qr-size="250"
data-qr-margin="2"
data-qr-error-correction="H"
data-qr-dark-color="#DC2626"
data-qr-light-color="#FFFFFF"
alt="High-quality red QR code" />Error Correction Levels
QR codes support different error correction levels that allow them to be read even when partially damaged:
| Level | Correction | Use Case |
|---|---|---|
L | ~7% | Clean environments, digital display |
M | ~15% | Standard use (default) |
Q | ~25% | Outdoor, possible dirt/damage |
H | ~30% | Industrial, harsh conditions |
Higher error correction means larger QR codes. For most use cases, M (default) is perfect.
Common Use Cases
Certificate Verification
<!DOCTYPE html>
<html>
<body style="font-family: Arial; padding: 60px;">
<h1 style="text-align: center;">Certificate of Achievement</h1>
<p style="text-align: center;">Awarded to: John Doe</p>
<div style="text-align: center; margin-top: 60px;">
<p><strong>Scan to verify authenticity:</strong></p>
<img data-qr="https://yourapp.com/verify/cert-2024-12345"
data-qr-size="150"
data-qr-error-correction="H"
alt="Verification QR Code" />
</div>
</body>
</html>Event Tickets
<!DOCTYPE html>
<html>
<body style="font-family: 'Courier New', monospace; padding: 40px;">
<h1>Tech Conference 2024</h1>
<div style="border: 2px dashed #333; padding: 20px; margin: 20px 0;">
<p><strong>Ticket:</strong> TKT-9876</p>
<p><strong>Seat:</strong> A-23</p>
<p><strong>Date:</strong> December 15, 2024</p>
</div>
<div style="text-align: center; margin-top: 30px;">
<p>Scan at entry:</p>
<img data-qr='{"ticket":"TKT-9876","seat":"A-23","date":"2024-12-15"}'
data-qr-size="250"
data-qr-error-correction="Q"
alt="Ticket QR Code" />
</div>
</body>
</html>Invoice Payment Links
<!DOCTYPE html>
<html>
<body style="font-family: Arial; padding: 40px;">
<h1>Invoice #INV-2024-001</h1>
<p><strong>Amount Due:</strong> $1,250.00</p>
<div style="border-top: 2px solid #eee; margin-top: 40px; padding-top: 20px; text-align: center;">
<p style="font-size: 16px; font-weight: bold;">Pay with Mobile</p>
<img data-qr="https://payments.yourapp.com/invoice/INV-2024-001"
data-qr-size="180"
alt="Payment QR Code" />
<p style="font-size: 12px; color: #666;">Scan to pay instantly</p>
</div>
</body>
</html>Product Labels
<!DOCTYPE html>
<html>
<head>
<style>
.label { border: 1px solid #000; padding: 10px; width: 200px; }
.label p { margin: 2px 0; font-size: 10px; }
</style>
</head>
<body>
<div class="label">
<p><strong>Widget Pro</strong></p>
<p>SKU: PRD-12345</p>
<p>Serial: WP-2024-5678</p>
<img data-qr="https://products.com/PRD-12345"
data-qr-size="120"
data-qr-margin="2"
alt="Product QR" />
</div>
</body>
</html>Contact Cards (vCard)
<!DOCTYPE html>
<html>
<body style="font-family: Arial; text-align: center; padding: 40px;">
<h2>John Doe</h2>
<p>Senior Developer @ Acme Inc</p>
<p>john@acme.com | +1-555-1234</p>
<div style="margin-top: 30px;">
<p style="font-size: 14px; color: #666;">Scan to save contact:</p>
<img data-qr="BEGIN:VCARD VERSION:3.0 FN:John Doe ORG:Acme Inc TEL:+1-555-1234 EMAIL:john@acme.com URL:https://acme.com END:VCARD"
data-qr-size="200"
alt="Contact vCard" />
</div>
</body>
</html>Use for newlines in vCard data when using HTML attributes.
Customization
Colored QR Codes
Create branded QR codes with custom colors:
<img data-qr="https://yourapp.com"
data-qr-dark-color="#DC2626"
data-qr-light-color="#FFFFFF"
data-qr-size="200" /><img data-qr="https://yourapp.com"
data-qr-dark-color="#2563EB"
data-qr-light-color="#FFFFFF"
data-qr-size="200" /><img data-qr="https://yourapp.com"
data-qr-dark-color="#059669"
data-qr-light-color="#FFFFFF"
data-qr-size="200" /><img data-qr="https://yourapp.com"
data-qr-dark-color="#7C3AED"
data-qr-light-color="#FEF3C7"
data-qr-size="200" />Ensure sufficient contrast between dark and light colors for reliable scanning. Dark-on-light works best.
Size Guidelines
| Use Case | Recommended Size | Notes |
|---|---|---|
| Business cards | 80-120px | Small, close scanning |
| Certificates | 150-200px | Standard documents |
| Posters | 300-500px | Distance scanning |
| Billboards | 1000px+ | Very large format |
Styling in HTML
<div style="border: 2px solid #333; padding: 20px; background: #f9f9f9; border-radius: 8px; display: inline-block;">
<p style="margin: 0 0 10px 0; font-weight: bold; text-align: center;">Scan to Verify</p>
<img data-qr="https://verify.com/cert-12345"
data-qr-size="200"
alt="QR Code" />
<p style="margin: 10px 0 0 0; font-size: 12px; text-align: center; color: #666;">
Certificate ID: #12345
</p>
</div>Batch Generation
Generate multiple PDFs with QR codes automatically - no pre-generation needed:
const certificates = [
{ id: 'cert-001', name: 'John Doe' },
{ id: 'cert-002', name: 'Jane Smith' },
{ id: 'cert-003', name: 'Bob Johnson' }
];
// Generate batch with inline QR codes
const batchResponse = await fetch('https://api.syntaxdoc.com/pdf/generate-batch', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
documents: certificates.map(cert => ({
fileName: `certificate-${cert.id}`,
htmlContent: `
<!DOCTYPE html>
<html>
<body style="text-align: center; padding: 40px;">
<h1>Certificate of Achievement</h1>
<p style="font-size: 18px;">Awarded to: <strong>${cert.name}</strong></p>
<div style="margin-top: 60px;">
<p>Verify certificate:</p>
<img data-qr="https://yourapp.com/verify/${cert.id}"
data-qr-size="180"
data-qr-error-correction="H"
alt="Verification QR Code" />
</div>
</body>
</html>
`
}))
})
});
const zipBlob = await batchResponse.blob();
// Download contains all PDFs with QR codes automatically generatedQR codes are generated in parallel during batch processing - extremely fast even for hundreds of documents!
Advanced Examples
Certificate with Multiple QR Codes
<!DOCTYPE html>
<html>
<body style="padding: 60px; font-family: Arial;">
<h1 style="text-align: center;">Certificate of Achievement</h1>
<div style="margin: 40px 0; text-align: center;">
<p>Awarded to: John Doe</p>
<p>Date: December 6, 2024</p>
</div>
<div style="display: flex; justify-content: space-around; margin-top: 60px;">
<div style="text-align: center;">
<img data-qr="https://verify.com/cert-12345"
data-qr-size="150"
alt="Verify" />
<p style="font-size: 12px;">Verify Certificate</p>
</div>
<div style="text-align: center;">
<img data-qr="https://share.com/cert-12345"
data-qr-size="150"
data-qr-dark-color="#2563EB"
alt="Share" />
<p style="font-size: 12px;">Share Certificate</p>
</div>
</div>
</body>
</html>Invoice with Payment QR
<!DOCTYPE html>
<html>
<body style="font-family: Arial; padding: 40px;">
<h1>Invoice INV-2024-001</h1>
<table style="width: 100%; margin: 30px 0;">
<tr><td>Amount Due:</td><td><strong>$1,250.00</strong></td></tr>
</table>
<div style="border-top: 2px solid #eee; padding-top: 30px; text-align: center;">
<p style="font-weight: bold;">Pay with Mobile</p>
<img data-qr="https://pay.yourapp.com/i/INV-2024-001"
data-qr-size="200"
alt="Payment QR" />
<p style="font-size: 12px; color: #666;">Scan to pay instantly</p>
</div>
</body>
</html>Product Label Sheet
Generate a sheet of product labels with QR codes:
const products = [
{ sku: 'PRD-001', name: 'Widget A' },
{ sku: 'PRD-002', name: 'Widget B' },
{ sku: 'PRD-003', name: 'Widget C' },
// ... up to 20 products
];
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<style>
.label-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
padding: 20px;
}
.label {
border: 1px solid #333;
padding: 15px;
text-align: center;
page-break-inside: avoid;
}
</style>
</head>
<body>
<div class="label-grid">
${products.map(p => `
<div class="label">
<img data-qr="https://products.com/${p.sku}"
data-qr-size="100"
data-qr-margin="1"
alt="${p.sku}" />
<p style="font-size: 10px; margin: 5px 0 0 0;">${p.sku}</p>
<p style="font-size: 9px; margin: 2px 0 0 0;">${p.name}</p>
</div>
`).join('')}
</div>
</body>
</html>
`;
// Generate single PDF with all labels
const formData = new FormData();
formData.append('files', new Blob([htmlContent], { type: 'text/html' }), 'index.html');
const response = await fetch('https://api.syntaxdoc.com/pdf/generate', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY' },
body: formData
});Best Practices
1. URL Shortening
For cleaner QR codes, use short URLs:
<!-- ❌ Long URL = complex QR code -->
<img data-qr="https://yourapp.com/certificates/verify?id=cert-2024-12345&type=completion&issued=2024-12-06" />
<!-- ✅ Short URL = simpler QR code -->
<img data-qr="https://yourapp.com/v/c12345" data-qr-size="180" />2. Test Scannability
Always test your QR codes:
- Use multiple QR code scanner apps
- Test on different devices (iOS, Android)
- Test at expected scanning distance
- Verify with damaged/crumpled printouts
3. Fallback Information
Always include human-readable information:
<div style="text-align: center;">
<img src="${qrCode}" width="180" height="180" />
<p style="font-size: 10px; margin-top: 10px;">
Or visit: yourapp.com/verify
<br>
Code: ${certId}
</p>
</div>4. Print Quality
For printed documents:
- Minimum size: 0.75 inches (2cm) square
- Use error correction level
QorH - Ensure adequate white margin (2+ modules)
- Test print quality before mass production
5. Color Contrast
<!-- ✅ Good contrast -->
<img data-qr="..." data-qr-dark-color="#000000" data-qr-light-color="#FFFFFF" />
<!-- ✅ Acceptable -->
<img data-qr="..." data-qr-dark-color="#1a1a1a" data-qr-light-color="#f5f5f5" />
<!-- ❌ Poor contrast (may not scan) -->
<img data-qr="..." data-qr-dark-color="#666666" data-qr-light-color="#999999" />Troubleshooting
QR Code Won't Scan
Common issues:
- Too small: Increase size to 150px minimum
- Low contrast: Use black on white
- Poor print quality: Increase DPI, use vector if possible
- Damaged: Increase error correction level
- Too much data: Shorten URL or reduce text
Data Limits
QR codes have capacity limits based on correction level:
| Correction | Numeric | Alphanumeric | Binary |
|---|---|---|---|
| L | 7,089 | 4,296 | 2,953 |
| M | 5,596 | 3,391 | 2,331 |
| Q | 3,993 | 2,420 | 1,663 |
| H | 3,057 | 1,852 | 1,273 |
Keep URLs under 100 characters for best results. Use URL shorteners for longer links.
Image Quality
For crisp QR codes in PDFs:
- Use
size: 200minimum for standard documents - Larger size doesn't increase file size much
- QR codes are already optimized compression
Security Considerations
URL Safety
- Use HTTPS URLs only
- Implement URL validation on your verify endpoint
- Add expiration timestamps to URLs
- Use signed tokens for sensitive verifications
Data Privacy
<!-- ❌ Don't encode sensitive data directly -->
<img data-qr="SSN:123-45-6789" />
<!-- ✅ Use secure reference IDs -->
<img data-qr="https://secure.yourapp.com/v/abc123xyz" data-qr-size="200" />Performance
QR codes are generated automatically during PDF creation with zero overhead:
- No additional API calls required
- Parallel generation for batch operations
- Cached and optimized for speed
- No impact on conversion limits (only the PDF counts)
Helper Function
Reusable function to build QR image tags:
function qrImage(data, options = {}) {
const size = options.size || 200;
const margin = options.margin || 1;
const errorCorrection = options.errorCorrection || 'M';
const darkColor = options.darkColor || '#000000';
const lightColor = options.lightColor || '#FFFFFF';
return `<img data-qr="${data}"
data-qr-size="${size}"
data-qr-margin="${margin}"
data-qr-error-correction="${errorCorrection}"
data-qr-dark-color="${darkColor}"
data-qr-light-color="${lightColor}"
alt="QR Code" />`;
}
// Usage in templates
const certificateHTML = `
<html>
<body>
<h1>Certificate</h1>
<p>Awarded to: John Doe</p>
${qrImage('https://verify.com/cert-123', { size: 180, errorCorrection: 'H' })}
</body>
</html>
`;