Best Practices

HTML Optimization for PDFs

Document Structure

Always use proper HTML5 structure for consistent results:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Document Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        /* CSS here */
    </style>
</head>
<body>
    <!-- Content here -->
</body>
</html>

CSS Best Practices

Typography for PDFs:
body {
    font-family: 'Arial', 'Helvetica', sans-serif;
    font-size: 12pt;
    line-height: 1.4;
    color: #333333;
    margin: 0;
    padding: 20px;
}

h1 { 
    font-size: 18pt; 
    margin-bottom: 12pt;
    page-break-after: avoid;
}

h2 { 
    font-size: 16pt; 
    margin-bottom: 10pt;
    page-break-after: avoid;
}

p { 
    margin-bottom: 8pt; 
    text-align: justify;
}
Page Break Control:
/* Keep content together */
.page-break { 
    page-break-before: always; 
}

.avoid-break { 
    page-break-inside: avoid; 
}

/* Prevent awkward breaks */
h1, h2, h3, h4, h5, h6 {
    page-break-after: avoid;
}

/* Table handling */
table {
    page-break-inside: auto;
}

tr {
    page-break-inside: avoid;
    page-break-after: auto;
}
Responsive Tables:
table {
    width: 100%;
    border-collapse: collapse;
    page-break-inside: avoid;
    margin-bottom: 20px;
}

th, td {
    padding: 8px 12px;
    border: 1px solid #ddd;
    text-align: left;
    vertical-align: top;
}

thead {
    background-color: #f5f5f5;
    font-weight: bold;
}

/* Ensure table headers repeat on new pages */
thead {
    display: table-header-group;
}

tbody {
    display: table-row-group;
}

Image Optimization

Responsive Images:
img {
    max-width: 100%;
    height: auto;
    image-rendering: optimizeQuality;
    display: block;
    margin: 10px 0;
}

/* High-DPI optimization */
@media (-webkit-min-device-pixel-ratio: 2) {
    img {
        image-rendering: -webkit-optimize-contrast;
    }
}
Image Guidelines:
  • Use compressed images (PNG for graphics, JPEG for photos)
  • Keep images under 2MB each
  • Embed small images as base64 data URLs
  • Use appropriate resolution (300 DPI for print quality)

API Usage Best Practices

Error Handling

Implement robust error handling with retry logic:
async function generatePDFWithRetry(html, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch('https://peedief.com/api/pdf', {
        method: 'POST',
        headers: {
          'x-api-key': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ html, options })
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`HTTP ${response.status}: ${errorText}`);
      }

      const result = await response.json();
      
      if (result.success) {
        return result;
      } else {
        throw new Error(result.error || 'Unknown error');
      }
    } catch (error) {
      console.error(`Attempt ${attempt} failed:`, error.message);
      
      if (attempt === maxRetries) {
        throw new Error(`PDF generation failed after ${maxRetries} attempts: ${error.message}`);
      }
      
      // Exponential backoff
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

Security Best Practices

API Key Management

DO

  • Store keys in environment variables
  • Use different keys per environment
  • Rotate keys periodically
  • Monitor key usage patterns
  • Use server-side API calls only

DON'T

  • Commit keys to version control
  • Share keys via email/chat
  • Use same key across projects
  • Embed keys in client-side code
  • Store keys in plain text files
Environment Configuration:
# .env file (never commit this!)
PEEDIEF_API_KEY=pk_live_your_secret_key_here
PEEDIEF_API_URL=https://peedief.com/api
// Proper server-side usage
const apiKey = process.env.PEEDIEF_API_KEY;
if (!apiKey) {
  throw new Error('PEEDIEF_API_KEY environment variable is required');
}

// NEVER do this in client-side code:
// const apiKey = 'pk_live_1234567890'; // ❌ NEVER!