PHP Java .NET Python Node.js Ruby Go Command Line API WebSave WordPress Zapier Make (formerly Integromat) Postman Bubble Integrately Appy Pie Pipedream Activepieces Pabbly

Save as PDF Button for Your Website

Add a Save as PDF button to your website, SaaS app, or customer portal without backend PDF code.

Overview

PDFCrowd WebSave adds a Save as PDF button to your website. Add a small JavaScript snippet and button so visitors can download the current page as PDF without backend PDF generation code.

Use WebSave as PDF when visitors need a polished PDF version of the current page. Compared with browser print, WebSave gives you more control over styling, backgrounds, layout, and page breaks.

Here is how a WebSave button can look on your website. Click it to see PDF conversion in action.

Is WebSave the Right Tool?

Use case Best fit
Add a button to your website, SaaS app, or customer portal. WebSave as PDF (this guide)
Add a button to WordPress posts or pages without custom code. Save as PDF WordPress plugin
Generate files from backend code, batch jobs, or server workflows. HTML to PDF API

Quick Start

Start with the recommended starter code. It includes the button, recommended PDF settings, and the WebSave script.

You can try the snippet with the demo key. For production, use your own WebSave key. See key setup.

Recommended Starter Code

Paste this block where the Save as PDF button should appear.

<!-- Button shown on your page -->
<button class="pdfcrowd-websave pdfcrowd-websave-style"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<!-- Recommended PDF settings -->
<script>
window.webSaveConfig = {
  apiSettings: {
    content_viewport_width: 'balanced'
  }
};
</script>

<!-- Load WebSave once, after the button and configuration -->
<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>
  • pdfcrowd-websave enables WebSave on the button.
  • pdfcrowd-websave-style adds default styling, icon, and spinner.
  • data-config points to window.webSaveConfig.

Choose URL or Content Mode

The starter code uses URL mode, which is the simplest choice for public pages. If your page is behind login, contains form input, or depends on client-side app state, use the comparison below to decide whether content mode is a better fit.

Scenario URL Mode Default Content Mode
Best for Public pages Login-protected pages, forms, and app state
How it works PDFCrowd fetches the page URL Browser sends current page HTML
Behind login Cannot access Works
Form values, user input Not included Preserved
Adjust URL parameters Supported Not available

Quick rule: Use URL mode for public pages. Use content mode when the PDF should include what the user currently sees, such as logged-in content, form values, or app state.

Content mode notes: Content mode captures the current page HTML and recreates it on PDFCrowd servers.

  • Content mode usually works best when the current browser state must be preserved. For complex pages, output can differ from URL mode because PDFCrowd recreates the page from captured HTML instead of opening the page URL directly.
  • It can include user-specific content and form values. See Data Security and Privacy for more about how PDFCrowd handles submitted content.

Use Content Mode for Logged-In Pages and Forms

The content mode is essential for pages requiring login, forms with user input, or any user-specific content. Enable it by setting conversionMode: "content" in the JavaScript configuration object.

In the default URL mode, PDFCrowd fetches a fresh page copy from your server, which means it cannot access pages behind login and won't see any form values users have entered. Content mode captures the actual HTML currently displayed and uploads it to the PDFCrowd service for conversion.

<!-- Button with content mode configuration -->
<button class="pdfcrowd-websave pdfcrowd-websave-style"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<script>
window.webSaveConfig = {
  // Enable content mode to capture current DOM state
  conversionMode: 'content',
  apiSettings: {
    content_viewport_width: 'balanced'
  }
};
</script>

<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>

Initialize Buttons Rendered After Page Load

WebSave automatically initializes buttons that are already on the page when the WebSave script loads. If your frontend framework renders the button later, initialize that button after it appears in the DOM:

window.WebSave.initButton(document.querySelector('#save-as-pdf'));

This applies to React, Vue, Angular, Svelte, and other apps that create DOM elements after the initial page load.

Recipes

Use these optional recipes when you need customization or advanced behavior.

Customize the Button and PDF Layout

You can customize the button appearance, filename, PDF generation, and many other settings.

Remove the pdfcrowd-websave-style class to use your own CSS styling instead of the default appearance. You can control the filename with the fileName option (static string or dynamic function), choose how the file opens with fileAction, and configure PDF layout through apiSettings.

See the complete options reference for all available customization options.

<!-- No pdfcrowd-websave-style class - use your own CSS -->
<button class="pdfcrowd-websave my-custom-button"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<!-- Customization configuration -->
<script>
window.webSaveConfig = {
  fileName: () => 'report-' + new Date().toISOString().split('T')[0] + '.pdf',
  fileAction: 'download',  // or 'open', 'openNewTab'

  // PDF conversion customization
  apiSettings: {
    content_viewport_width: 'balanced',
    page_size: 'Letter',
    margin_top: '0.75in',
    margin_bottom: '0.75in'
  }
};
</script>

<!-- Custom CSS for the button -->
<style>
.my-custom-button {
  background: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.my-custom-button:hover {
  background: #0056b3;
}
.my-custom-button:disabled {
  opacity: 0.6;
  cursor: wait;
}
</style>

<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>
PDF Button Configuration Tool: Use the configuration tool to adjust margins, headers, page layout, and other settings, then generate ready-to-use WebSave code.

Create a Print-Friendly PDF

Use this recipe when the saved PDF should omit page chrome such as navigation, ads, sidebars, or footers. Common cleanup options include:

  • URL parameters: If your server recognizes print parameters like ?print=1, modify the URL before conversion to request a print-friendly version.
  • Print stylesheets: Apply existing @media print CSS rules using the use_print_media setting.
  • Custom CSS injection: Add styles at conversion time using custom_css to hide elements or adjust layouts.
  • JavaScript preprocessing: Run JavaScript before conversion using custom_javascript to remove or modify content dynamically.
  • Element removal: Add the pdfcrowd-remove class to any HTML element you want excluded from the PDF.

The recipe shows these options together; keep only the parts that fit your page.

<button class="pdfcrowd-websave pdfcrowd-websave-style"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<!-- Method Selection Guide:
   - URL parameters: Best when server has print-specific templates
   - Print stylesheets: Quick option if @media print CSS exists
   - Custom CSS: Flexible styling without modifying HTML
   - JavaScript: Dynamic content manipulation
   - pdfcrowd-remove class: Simple for removing static elements -->

<script>
window.webSaveConfig = {

  // Method 1: URL parameters, adds ?print=1 (URL mode only)
  onBeforeConversion: function(config) {
    if (config.conversionMode === 'url') {
      const url = new URL(config.url);
      url.searchParams.set('print', '1');
      config.url = url.toString();
    }
    return false; // Proceed with conversion
  },
  
  apiSettings: {
    // Method 2: Print stylesheets
    // use_print_media: true,
    
    // Method 3: Custom CSS injection
    custom_css: `
      /* Hide elements in PDF */
      .advertisement, .sidebar, footer { 
        display: none !important; 
      }
      /* Adjust layout for print */
      .content { 
        width: 100% !important; 
        max-width: none !important; 
      }
    `,
    
    // Method 4: JavaScript preprocessing
    custom_javascript: `
      // Remove dynamic content before conversion
      document.querySelectorAll('.video-player, .chat-widget').forEach(el => {
        el.remove();
      });
      // Expand collapsed sections
      document.querySelectorAll('.collapsed').forEach(el => {
        el.classList.remove('collapsed');
      });
    `,
    
    content_viewport_width: 'balanced'
  }
};

</script>

<!-- Method 5: Use pdfcrowd-remove class directly in HTML
     Add this class to elements in your actual page content: -->
<nav class="pdfcrowd-remove">
  This navigation won't appear in the PDF
</nav>

<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>

Add Error Handling and Analytics

You can add error handling with custom UI, success tracking for analytics, pre-conversion validation, and more. This recipe shows how to integrate WebSave with your application's workflow.

<!-- Advanced customization with callbacks -->
<button class="pdfcrowd-websave pdfcrowd-websave-style"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<script>
// Application-specific hooks. Replace these with your own UI, analytics,
// and permission checks:
// - showCustomErrorModal(message, code) - your error UI
// - trackEvent(name, data) - your analytics
// - userIsLoggedIn() - your auth check

window.webSaveConfig = {

  // Custom error handling
  onError: function(errorMessage, statusCode) {
    console.error('WebSave error:', errorMessage, 'Code:', statusCode);
    
    // Display your own error UI instead of default dialog
    showCustomErrorModal(errorMessage, statusCode);
    
    return true; // Return true to prevent default error dialog
  },
  
  // Track successful conversions
  onFileCreated: function(blob) {
    // Log success for analytics
    trackEvent('pdf_generated', {
      size: blob.size,
      page: window.location.pathname
    });
    
    return false; // Return false to let WebSave handle download
  },
  
  // Pre-conversion validation (optional)
  onBeforeConversion: function(config) {
    // Validate or modify before conversion starts
    // Example: Check if user is logged in
    if (!userIsLoggedIn()) {
       alert('Please log in to download PDF');
       return true; // Cancel conversion
    }

    return false; // Proceed with conversion
  },

  // PDF generation settings
  apiSettings: {
    content_viewport_width: 'balanced'
  }
};
</script>

<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>

Authentication

How WebSave Keys Work

Each WebSave key is tied to the domain or subdomain you enter when creating the key. This lets you include the key in client-side code - if someone copies it, they cannot use it on their own website. The key is provided via the data-key attribute on your conversion button.

Getting Your Keys

The recipes use a demo key demo for testing. To get your own WebSave key:
  1. Choose a license plan.
  2. Create your WebSave keys.

Key Management Options

  • Create separate keys for unrelated domains and subdomains.
  • Enable "Include subdomains" when one key should cover subdomains under the entered site.
  • You can generate multiple keys per site for various sections or teams.
  • Use separate keys for staging and production environments.
  • Revoke and regenerate keys anytime if needed.

Error Handling

WebSave handles common error states automatically. You only need custom error handling when you want to use your own UI or logging.

Built-in Error Recovery

  • Retries temporary 502/503 server errors up to 3 times.
  • Disables the button during conversion and re-enables it afterwards.
  • Prevents multiple simultaneous conversions from the same button.

Error Display Options

Without configuration, WebSave shows a default error dialog after automatic recovery attempts. Use the onError callback if you want to customize the final error presentation.

Implementing Custom Error Handling

Use the onError callback to customize error handling. This recipe shows a simple custom error handler with user-friendly messages and console logging:

<button class="pdfcrowd-websave"
        data-key="demo"
        data-config="webSaveConfig">
  Save as PDF
</button>

<script>
window.webSaveConfig = {
  onError: function(errorMessage, statusCode) {
    // Log to console for debugging
    console.error('WebSave Error:', {
      message: errorMessage,
      code: statusCode,
      url: window.location.href
    });
    
    // Show user-friendly message
    let userMessage = 'Unable to generate PDF. Please try again.';
    if (statusCode === 429) {
      userMessage = 'Too many requests. Please wait a moment and try again.';
    } else if (statusCode >= 500) {
      userMessage = 'Service temporarily unavailable. Please try again later.';
    }
    
    // Display to user
    alert(userMessage);
    
    // Return true to suppress default dialog
    return true;
  }
};
</script>

<script src="https://edge.pdfcrowd.com/websave/1.3.0/websave.min.js" async></script>

For detailed error code information, see the Status Codes Reference.

Troubleshooting

This guide helps you diagnose and resolve common WebSave integration issues. For automatic error recovery and customization options, see the Error Handling section above.

Button Not Working

Button doesn't respond to clicks

  • Verify the button has the correct class: pdfcrowd-websave
  • Check that data-key attribute contains your WebSave key
  • Ensure the WebSave script loads
  • Confirm your page is served over HTTPS - WebSave requires secure connections
  • Open browser console and check for JavaScript errors or security warnings

Invalid WebSave key error

  • Verify the key matches the domain or subdomain where your page is hosted
  • Check the key scope in your WebSave dashboard: "Exact only" keys do not work on subdomains
  • For example, a key for example.com works on www.example.com only when "Include subdomains" is enabled
  • A key for www.example.com with "Include subdomains" covers deeper subdomains such as app.www.example.com, not sibling sites such as dev.example.com
  • Check that you're using a WebSave key (not a regular API key)
  • Ensure the key is active

Works on one subdomain but not another

WebSave key scope follows the exact site entered when the key is created. A key for example.com with "Include subdomains" works on www.example.com and dev.example.com. A key for www.example.com works on www.example.com and, with "Include subdomains", on deeper subdomains such as app.www.example.com. It does not work on sibling sites such as dev.example.com.

Custom URL mode target rejected

In URL mode, WebSave normally converts the current page URL. If your JavaScript changes the URL to be converted, the browser same-origin check still uses exact host matching. example.com and www.example.com are different origins, even if the WebSave key includes subdomains. Use content mode when you need to convert the current browser page state.

Not working on localhost

WebSave cannot access localhost URLs as conversions happen on PDFCrowd servers. Use ngrok or localtunnel to create a temporary public HTTPS URL for your local development server.

Button not working in reactive frameworks

Content Not Captured Correctly

Pages behind login or with user input

URL mode fetches a fresh page from your server. Use conversionMode: "content" in your JavaScript configuration for:

  • Pages behind login/authentication
  • Form values and user input
  • User-modified content after page load
  • Single-page application state

See Use Content Mode for Logged-In Pages and Forms for implementation.

JavaScript-generated or AJAX content missing

For dynamic content, either use content mode or add javascript_delay to wait for content to load:

window.webSaveConfig = {
  apiSettings: {
    javascript_delay: 2000,  // Wait 2 seconds for JS/AJAX
  }
}

Wrong responsive layout or content cut off

PDFs may show mobile layout instead of desktop (or vice versa) based on viewport width. Set content_viewport_width to control which responsive breakpoint is used:

window.webSaveConfig = {
  apiSettings: {
    content_viewport_width: "1280px",  // Force desktop layout
  }
}

Common widths: Mobile (375-414px), Tablet (768-834px), Desktop (1280-1920px).

Debugging Tools and Techniques

WebSave provides two debugging options to help diagnose different types of issues:

  • verbosity logs WebSave events (button clicks, API calls, key validation) to your browser console - useful for integration and configuration issues.
  • debug_log captures what happens on PDFCrowd servers (resource loading, timeouts) - helpful for content and layout problems. Find these logs in your conversion log.
window.webSaveConfig = {
  verbosity: 1,  // Client-side: logs events to browser console
  apiSettings: {
    debug_log: true,  // Server-side: saves details to conversion log
  }
};

Getting Help

If you're still experiencing issues after trying these solutions:

When contacting support, include:

  • Your WebSave configuration code
  • The URL where the issue occurs (or a test page demonstrating the problem)
  • Browser console output with verbosity: 1 enabled
  • Screenshots of any error messages