Somebody books a slot, buys a ticket, or requests a quote. The follow-up they expect is a document: an invoice they can forward to accounting, a ticket they can show at the door, or a confirmation with the details in writing.
In most WordPress form plugins that means a second plugin. Fluent Forms ships it as a separate Fluent PDF Generator plugin. Gravity Forms users install Gravity PDF. Formidable sells it as an add-on. The form collects the data, and something else turns it into a PDF.
CraftForms has the PDF builder in the core plugin, and it’s in the free version. You design the document in the same block editor you use for pages. Merge tags pull in the submission data. A QR or barcode block draws a code that’s unique to each document. You then choose where the file goes: the confirmation email, the saved submission, or (in Pro) the order.
This guide builds an event ticket with a scan-in QR code, then covers invoices and the order side.

The model: PDFs attach to something
The design choice that matters most: there is no standalone “Generate PDF” step in the form’s submit actions. An earlier version had one, and it confused people. If nothing emailed or stored the file, it effectively went nowhere.
So a PDF now attaches to something that owns it. Three places have an Attach PDF(s) setting:
| Attachment point | Where the file ends up | Plan |
|---|---|---|
| Save Submission action | Documents section of the submission’s detail view, with download links | Free |
| Send Email (Plain Text) / Send Email (Template) action | Attached to that email | Free |
| Catalog item → Attach PDF(s) panel | Documents section of the order created from the form | Pro |
Email actions also have an Attach files picker for static Media Library files, like terms and conditions or a venue map, next to the generated PDFs.
If the same template is picked in two places, it’s rendered once. The first action that needs it generates the file, and later actions reuse it. The customer’s email attachment and the admin’s download link are the same document.
Step 1: Create a PDF template
Go to CraftForms → PDF Templates → Add New. A starter picker opens with three designs:
- Basic Invoice: A4 portrait
- Event Ticket: A5 landscape, with a QR code
- Shipping Label: 4×6 in, with a Code 128 barcode
You can also Start from scratch or Import from file (templates export and import like forms). Pick Event Ticket.
This is the regular block editor with a few PDF-specific settings. The Page panel in the sidebar sets:
- Page size: A3, A4, A5, Letter, Legal, or Custom (width and height in mm)
- Orientation: Portrait or Landscape
- Margins (mm): top, right, bottom and left
The canvas is sized to the page, and a red guide line shows where each page break falls. That line is useful: if your invoice spills onto a second page, you see it while editing.

Step 2: Fill it with submission data
Text in the template takes merge tags in double curly braces. The Dynamic Data panel lists them, so you don’t have to memorise names. The ones you’ll use most:
| Tag | Resolves to |
|---|---|
{{email.<field>}} | A form field value, e.g. {{email.name}}, {{email.email}}, {{email.address}} |
{{all_fields.table}} | Every submitted field as a ready-made table (good for “copy of your submission” PDFs) |
{{site.name}}, {{site.url}} | Your site |
{{date.date}}, {{date.time}} | When the submission happened |
{{pdf.number}} | The document number (see below) |
{{pdf.generated_at}} | Render timestamp |
{{order.id}}, {{order.total}}, {{order.currency}}, {{order.token}} | The order the form created (Pro, catalog/checkout forms) |
email. is the prefix for form fields in every CraftForms template (emails and PDFs), so a tag that works in your confirmation email works in the PDF too.
About {{pdf.number}}. When the PDF is attached through Save Submission, it’s the saved submission’s ID. When the form created an order (Pro), it’s the order ID. That gives every document a unique number with no extra setup.
Step 3: Add a QR code that’s unique per ticket
The Event Ticket starter already has a QR Code / Barcode block. Select it and look at its settings:
- Type: QR Code, Code 128, EAN-13 or UPC-A
- Value: can be a merge tag
- Error-correction level (for QR codes), foreground/background colour, and size
The value is resolved per document, on the server, before the code is drawn. Set it to a merge tag and each ticket gets its own code. The editor shows a sample preview, and the real code is generated when the PDF is rendered.
What to encode:
- Free, Save Submission path:
{{pdf.number}}. That’s the submission ID. At the door, look it up under Submissions. - Pro, catalog or checkout form:
{{order.token}}. That’s the order’s unique token, which is what the starter uses. A token is harder to guess than a sequential ID, which matters if the QR code is the thing that gets someone in.
A value the symbology can’t encode (a 12-digit string in an EAN-13 block, or a tag that resolved to nothing) doesn’t break the document. The PDF still generates; the code is just left out or replaced with a placeholder.
Publish the template. (Drafts also appear in the attach pickers, so you can test before going live.)

The Event Ticket starter, rendered by the real generator with sample data. The font is embedded automatically.
Step 4: Attach it to the form
Open your registration form and go to its submit actions.
- Save Submission: open its settings, find Attach PDF(s), and tick Event Ticket.
- Send Email (Template) (or Plain Text) to the attendee: tick the same Event Ticket under Attach PDF(s). Optionally add a venue map under Attach files.
- Optionally, a second email to yourself with the same attachment.
Order matters here. Put Save Submission above the emails. The file is generated once by whichever action gets to it first. If Save Submission runs first, {{pdf.number}} has a value and every copy (email attachment and admin download) shows the ticket number. If an email runs first, there’s no submission ID yet, and the shared file has an empty number.

Submit the form once. The attendee gets an email with Event Ticket.pdf attached. In Submissions, the entry’s detail view has a Documents section with the same file.

What happens when it renders

Two things set this apart from “print the page to PDF”:
It’s all server-side. No visitor browser is involved after you save the template. That’s what lets it work for triggers without a browser. The renderer is Dompdf, bundled with the plugin, so there’s nothing to install on the server and no headless Chrome to maintain.
The compiler knows what Dompdf can’t do. Server-side PDF engines don’t support flexbox or grid, and block-editor columns are built on flexbox. When you save a template, CraftForms converts columns to tables and inlines the styles, including fixed-width columns next to flexible ones (the classic “logo left, invoice details right” header). The fonts your theme uses are embedded automatically, from the theme’s font files or Google Fonts, so the PDF doesn’t fall back to a generic typeface.
Files aren’t public. Generated PDFs are stored in a protected folder, not the Media Library. Invoices contain names, addresses and prices, so each download link carries a per-file token rather than a guessable URL.
Invoices
The Basic Invoice starter works the same way: A4, your site name at the top, customer details from {{email.*}}, {{order.total}} and {{order.currency}} for the amount, and {{pdf.number}} as the reference.
For a quote or order form without the Pro order system, attach it through Save Submission and point the totals at your form’s price fields instead of order.*. The number is the submission ID.
For catalog and checkout forms (Pro), open the catalog item and use its Attach PDF(s) panel. The selected templates are generated when the order is created and linked to it. They appear in the Documents section of the order’s detail view, and {{order.*}} tags are filled in. This panel only lists published templates.
What’s free and what’s Pro
| Free | Pro | |
|---|---|---|
| PDF Templates builder, starters, QR/barcode block | ✅ | ✅ |
| Attach to Send Email actions | ✅ | ✅ |
| Attach to Save Submission (Documents in submission detail) | ✅ | ✅ |
| Custom page sizes, auto font embedding, protected storage | ✅ | ✅ |
| Catalog item → attach to order (Documents in order detail) | ✅ | |
{{order.*}} tags (orders are a Pro feature) | ✅ |
Building and generating PDFs is free. Linking documents to orders is Pro, because orders are Pro.
Limits worth knowing
- Designed for short documents. Tickets, invoices, labels and confirmations fit on one or two pages. On multi-page documents, page margins aren’t repeated at intermediate page breaks.
- No flexbox or grid effects beyond columns. Columns, groups, images, tables and text all translate. Layout tricks that only work with flexbox or grid won’t.
- Template changes apply on re-save. The compile step runs when you save the template, so edit, then Update.
- Not a signature tool. There’s no signature field yet. It’s on the roadmap, and when it ships, the captured signature will be usable in PDF templates.
Try it
- CraftForms → PDF Templates → Add New → pick Event Ticket.
- Set the QR block’s value to
{{pdf.number}}and publish. - On your form: Save Submission → Attach PDF(s) → Event Ticket.
- Below it: Send Email (Template) → Attach PDF(s) → Event Ticket.
- Submit once. Check your inbox and the submission’s Documents section.
That’s the whole setup, with no second plugin.
Related: Email templates + testing with Mailtrap








































