Web-to-print
The print designer lays out business cards, flyers, postcards, badges, posters and stickers in the page, on the product's real size with its bleed, trim and safe lines drawn and snapped to. It places text (straight or on a curve), pictures with their resolution worked out where they sit, shapes, QR codes and barcodes, and tables, on as many sides or pages as the product has, in RGB, CMYK or your own spot colours.
It is made for online print shops, brand portals and marketing tools. You build a template and mark which parts a customer may change; in customer mode only those can be touched, as a short form, while the checks a print shop makes - text that does not fit, a soft photo, ink past the limit - run as they type. One design fills in from a CSV file of names, shows on a photo of the product, and goes out as a print-ready PDF with bleed, crop and registration marks, one page per record. The same engines run in Node for an order pipeline.
Try it with your own pictures, fonts and CSV files in confidence: they are opened by your browser, on your device. Nothing is uploaded, no copy reaches us or anyone else, and nothing is kept once you close this tab.
A business card template, filled in by a customer
Kirkgate Press, a made-up print shop in Leeds, has set up a card template for an invented practice, Fernhill Vets: the green band, the logo, the address and the QR code are locked; each vet may change only the photo, name, job title and contact lines. Fill it in as Priya Nair, whose photo is too small for print, see what the checks say, put it right, and take the print-ready PDF with its marks.
// Node 20 or later, from the Gold package: fill the template from a web order, check it, and write the print-ready PDF.
import { readFileSync, writeFileSync } from 'node:fs';
import { readDocument, templateFields, updateObject, checkPrintDocument, writePrintPdf, pdfImageFromBytes } from './dist/node/bmx-print-designer.mjs';
const { document: template } = readDocument(readFileSync('templates/fernhill-card.json', 'utf8'));
const order = JSON.parse(readFileSync('orders/KP-48213.json', 'utf8')); // { fields: { name, title, contact }, photo: 'KP-48213.png' }
// Only what the template lets a customer change is taken from the order.
let card = template;
for (const { page, object } of templateFields(template)) {
const value = object.type === 'image' ? order.photo : order.fields[object.id];
if (value !== undefined) card = updateObject(card, template.pages.indexOf(page), object.id, object.type === 'image' ? { src: value } : { text: value });
}
const photo = await pdfImageFromBytes(readFileSync(`uploads/${order.photo}`));
const images = new Map([[order.photo, { width: photo.width, height: photo.height }]]);
const problems = checkPrintDocument(card, { images });
for (const p of problems) console.log(`${p.severity}: ${p.kind} on ${p.object} ${p.detail ?? ''}`);
if (problems.some(p => p.severity === 'error')) process.exit(1);
writeFileSync('print/KP-48213.pdf', await writePrintPdf(card, { images, pdfImages: new Map([[order.photo, photo]]), title: 'Order KP-48213' }));
Conference badges from a list of names
An A6 badge for Calder Data Day, a made-up conference at an invented mill in Halifax. The front holds fields for the name, company and role, a Code 128 barcode of the ticket number and a QR code with the person's contact card; the back has the day's programme as a table with each person's own workshop in it. Load the eight invented attendees, step through them, see a badge on a lanyard, and take the whole run as one PDF.