Printing from Bubble: The API Approach That Actually Works
If you are building a point-of-sale system, a booking platform, or any no-code app that needs to trigger a physical printer, the solution is PrintNode. It bridges the gap between a web application and a local or network printer by receiving an API call from your Bubble app and forwarding the print job to a lightweight client installed on a device in your office or workspace. The setup is more approachable than it sounds, but there are two specific configuration details that catch nearly every builder the first time.
The Authentication Gotcha: HTTP BASIC, Not a Header Key
Most APIs that provide an API key expect you to pass it as a private key header, typically formatted as Authorization: Bearer [key]. PrintNode is different. Their documentation is clear but easy to skim past: you submit the API key as the username in HTTP BASIC authentication, leaving the password field completely empty.
In the Bubble API Connector, this means selecting Basic Authentication and placing your PrintNode API key in the username field. Do not add it as a header value. That single configuration error is the most common reason PrintNode integrations fail at the first test.
Two Ways to Deliver the File to PrintNode
Once authenticated, you have two options for how to send the document you want to print.
The first is to provide a URI, the hosted URL of the file. If a PDF has been uploaded to your Bubble app, you can pass its storage URL directly to PrintNode. The consideration here is access control. If the file is stored privately in Bubble, PrintNode cannot fetch it because it has no session cookie. You would need to either make the file publicly accessible or use the Base64 approach.
The second option is Base64 encoding, which encodes the file contents as a text string that travels in the API request body. This avoids access control issues entirely since the data is included inline. The practical trap here is initialization: pasting even a two-page all-text PDF as a Base64 value into the API Connector body field generates an enormous string that can crash the browser tab. The workaround is to initialize the call with the smallest possible Base64-encoded PDF, a single word on one page, then swap in the dynamic value for actual use.
Generating Print-Ready PDFs in Bubble
Sending a file to PrintNode is only half the problem. Generating a high-quality PDF from your Bubble data is the other half. Screenshot-based plugins are worth avoiding here: they produce low-resolution images, text that is not sharp at print scale, and unpredictable page breaks when a repeating group spans multiple pages.
Better options include:
- PDF Creator by Cranford Tech: Produces clean, text-sharp PDFs with proper page break handling. A good default choice for invoices and receipts.
- AllShots: Works similarly to Canva with an API, letting you design a template, insert dynamic fields, and receive a PDF or image back.
- Templated: Template-based PDF generation where you send structured JSON data and receive a rendered PDF. Similar in concept to sending a transactional email through a template provider.
If any of these services temporarily host the generated PDF on their own servers before returning it, you can take advantage of that by passing the temporary URL directly to PrintNode rather than encoding it as Base64. PrintNode fetches, downloads, and prints the file before the hosted copy expires.
Putting It Together
The full integration involves creating a print job via the PrintNode API, specifying either the document URI or Base64 content, and targeting the correct printer ID from your PrintNode account. You can retrieve a list of connected printers through a separate API call, which makes it possible to let users select their printer dynamically in the Bubble UI rather than hardcoding a single device.
For anyone building apps where receipts, invoices, labels, or any physical document output is part of the user flow, this combination of the Bubble API Connector and PrintNode provides a reliable, production-ready printing solution without requiring any custom server infrastructure.