WebSave as PDF lets your users save any webpage as PDF with one click. Simply add our JavaScript library and a button to your HTML - no server-side setup required.
Perfect for: Reports, invoices, documentation, and any content that needs professional PDF formatting. Unlike browser print, WebSave as PDF preserves exact styling, backgrounds, and layouts without unexpected page breaks.
Try it: Save this documentation as PDF using the WebSave button below.
The following examples demonstrate WebSave's capabilities, from basic setup to advanced integration. Each example builds on previous concepts, so you can start simple and add features as needed. Copy any example into your webpage to get started.
Note: WebSave requires a key. Examples below use a demo key for testing, sign up to get your WebSave keys. Learn how keys work.
Minimal working example for public web pages.
The pdfcrowd-websave-style
class provides default button styling.
<!-- Load WebSave script (place before closing </body> tag) --> <script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <!-- Add conversion button (place anywhere in your page) class="pdfcrowd-websave" - Required: Enables WebSave functionality class="pdfcrowd-websave-style" - Optional: Applies default button styling data-key - Your domain-locked WebSave key data-config - Links to configuration object below --> <button class="pdfcrowd-websave pdfcrowd-websave-style" data-key="demo" data-config="webSaveConfig"> Save as PDF </button> <!-- WebSave configuration --> <script> window.webSaveConfig = { apiSettings: { content_viewport_width: 'balanced' } }; </script>
WebSave offers two ways to capture your page. This table helps you choose:
Scenario | URL Mode Default | Content Mode |
---|---|---|
Best for | Public pages | Login-protected pages, forms |
How it works | Server fetches fresh page | Captures current browser view |
Layout preservation | ✓ Clean, predictable | ~ May break complex layouts |
Behind login | ✗ Cannot access | ✓ Works |
Form values, user input | ✗ Lost | ✓ Preserved |
Adjust URL parameters | ✓ Supported | ✗ Not available |
Quick rule: If your page is publicly accessible, use URL mode. Only use content mode when you must capture login-protected content or form data.
Important: Content mode captures your page as raw HTML and recreates it on our server. This process can sometimes break complex layouts, especially those relying on specific browser behaviors or external resources. Use URL mode whenever possible for best results.
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.
<script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <!-- Button configuration - content mode now set in JavaScript config --> <button class="pdfcrowd-websave pdfcrowd-websave-style" data-key="demo" data-config="webSaveConfig"> Save as PDF </button> <script> window.webSaveConfig = { // NEW: Enable content mode to capture current DOM state conversionMode: 'content', apiSettings: { content_viewport_width: 'balanced' } }; </script>
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.
<script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <!-- 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 convwrsion 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>
Converting complex web pages to clean PDFs can be challenging. Elements like navigation bars, ads, and sidebars that work well on screen often clutter printed documents. WebSave provides several methods to create print-optimized PDFs:
?print=1
,
modify the URL before conversion to request a print-friendly version.
@media print
CSS rules using the
use_print_media
setting.
custom_css
to hide elements or adjust layouts.
custom_javascript
to remove or modify content dynamically.
pdfcrowd-remove
class to any HTML element
you want excluded from the PDF.
These methods can be used individually or combined. The example below demonstrates each approach with explanatory comments.
<script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <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>
You can add error handling with custom UI, success tracking for analytics, pre-conversion validation, and more. This example shows how to integrate WebSave with your application's workflow.
<!-- Advanced customization with callbacks --> <script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <button class="pdfcrowd-websave pdfcrowd-websave-style" data-key="demo" data-config="webSaveConfig"> Save as PDF </button> <script> // This example assumes you have these functions defined: // - 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>
WebSave uses domain-locked keys for security. Each key is tied to a specific
domain when created and will only work on that domain. This means your WebSave
key can be safely included 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.
demo
for testing. To get
your own WebSave key:
WebSave provides comprehensive error handling that works automatically without any configuration. The system includes built-in error recovery mechanisms and displays clear feedback when issues occur. You can customize how errors are presented to users while keeping the automatic recovery features.
These features work automatically for all conversions, regardless of how you handle error display:
When an error occurs after automatic recovery attempts, WebSave needs to inform the user. You have two options:
Without any configuration, WebSave shows a professional modal dialog that includes:
The default dialog provides a good user experience out of the box. You only need custom error handling if you want to integrate with your own UI or error tracking systems.
Use the onError
callback to control how errors are shown to users. The automatic retry
and button state management still happen - you're only customizing the final error presentation.
Use the onError
callback to customize error handling. This example shows a complete
production-ready implementation with user-friendly messages, console logging, and error tracking:
<script src="https://edge.pdfcrowd.com/websave/1.0.0/websave.min.js" async></script> <button class="pdfcrowd-websave" data-key="demo" data-config="webSaveConfig"> Save as PDF </button> <script> // This example assumes you have these functions defined: // - showNotification(message) - displays message to user // - trackError(eventName, data) - sends error to tracking service 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 showNotification(userMessage); // Track error for monitoring trackError('pdf_generation_failed', { message: errorMessage, code: statusCode, url: window.location.href }); // Return true to suppress default dialog // Return false to show default dialog (with your logging still running) return true; } }; </script>
verbosity: 1
in configuration to enable console loggingFor detailed information about specific error codes and their solutions, see the Status Codes Reference. Common status codes in WebSave:
This guide helps you diagnose and resolve common WebSave integration issues. For automatic error recovery and customization options, see the Error Handling section above.
pdfcrowd-websave
data-key
attribute contains your WebSave keyWebSave 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.
URL mode fetches a fresh page from your server. Use conversionMode: "content"
in your JavaScript configuration for:
See Example 2 for implementation.
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 } }
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).
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 } };
If you're still experiencing issues after trying these solutions:
When contacting support, include:
verbosity: 1
enabledSee the WebSave Reference for all configuration options including page layout, PDF settings, headers/footers, watermarks, and advanced conversion controls.