Integration recipes
Short, copy-paste starting points for the pages of a typical e-shop, plus one server-side flow. Each recipe states the goal, shows the code and links to the guides and examples that explain the details. Replace {API_KEY} with your website integration API key and the product codes with your own.
TIP
Runnable versions: the recipes are based on the integration examples · source — see Examples for the full list.
Every browser recipe assumes the integration script is on the page (see Loading the integration script):
<script async src="https://app.trondesigner.com/js/website-integration.js" referrerpolicy="origin"
data-td-api="https://app.trondesigner.com/api" data-td-api-key="{API_KEY}"></script>Define any callback functions named in data-td-*-callback attributes before this tag, as global functions.
1. Product page: "Design your print" → cart
Goal: a button on the product detail page opens the editor for a catalog product; when the print job is saved, its GUID goes into the cart line.
<script>
// Receives a DesignerEntityEvent: { entityType, eventType, entityGuid, detail }
async function onPrintJobSaved(event) {
const { printJobGuid, code } = event.detail;
// PUT = upsert: `created` and later `updated` events arrive with the same printJobGuid
await fetch(`/cart/lines/${printJobGuid}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ productCode: '10086021', quantity: 1, printJobGuid, printJobCode: code }),
});
}
</script>
<script async src="https://app.trondesigner.com/js/website-integration.js" referrerpolicy="origin"
data-td-api="https://app.trondesigner.com/api" data-td-api-key="{API_KEY}"
data-td-print-job-created-callback="onPrintJobSaved"
data-td-print-job-updated-callback="onPrintJobSaved"></script>
<button data-td-action="OpenCreate"
data-td-supplier-code="PFC"
data-td-product-code="10086021"
data-td-print-position-code="front"
data-td-print-technology-code="PAD03">
Design your print
</button>The editor can save the print job more than once in one session (for example with a Save button and again at the final confirmation). Depending on the save it fires created or updated, always with the same GUID — so listen to both and upsert the cart line by printJobGuid instead of adding a new one. The GUID also stays the same when the customer edits the design later. Read more: HTML data attributes, Events and callbacks, Result actions (what happens after the customer confirms). Example: Attributes - Overview.
2. Cart: "Edit design"
Goal: each cart line with a design gets a button that reopens the same print job for editing.
<script>
function onPrintJobUpdated(event) {
refreshCartLine(event.entityGuid); // your code: reload the thumbnail or price of that line
}
</script>
<script async src="https://app.trondesigner.com/js/website-integration.js" referrerpolicy="origin"
data-td-api="https://app.trondesigner.com/api" data-td-api-key="{API_KEY}"
data-td-print-job-updated-callback="onPrintJobUpdated"></script>
<!-- rendered by your cart template for every line that has a print job -->
<button data-td-action="OpenEdit" data-td-print-job-guid="{{ line.printJobGuid }}">Edit design</button>If your cart renders the buttons after the script has initialized (for example in a single-page app), call window.tronDesigner.refreshRegisteredElements() afterwards. From JavaScript, the same is window.tronDesigner.setPrintJob(printJobGuid, 'Edit').open({ mode: 'dialog' }). Read more: Open modes. Example: Edit Mode.
3. Order confirmation: read-only preview
Goal: show the ordered design as images, with a button that opens it read-only.
<div id="design-preview"></div>
<button data-td-action="OpenView" data-td-print-job-guid="{{ order.printJobGuid }}">View design</button>
<script>
const PRINT_JOB_GUID = '{{ order.printJobGuid }}';
async function showPreview() {
const td = window.tronDesigner;
const printJob = await td.getPrintJob(PRINT_JOB_GUID);
for (const printing of printJob?.printings ?? []) {
const blob = await td.getPrintingImage(PRINT_JOB_GUID, printing.printingGuid);
if (!blob?.size) continue; // undefined, or an empty Blob when there is no image
const img = document.createElement('img');
img.src = URL.createObjectURL(blob);
img.alt = `${printing.printData.positionName} – ${printing.printData.technologyName}`;
document.getElementById('design-preview').append(img);
}
}
</script>
<script async src="https://app.trondesigner.com/js/website-integration.js" referrerpolicy="origin"
data-td-api="https://app.trondesigner.com/api" data-td-api-key="{API_KEY}"
data-td-script-initialized-callback="showPreview"></script>getPrintingImage returns the product image with the design; pass a product variant code as the third argument for a specific variant. Use getPrintingMotive for the design alone. Read more: Retrieving print jobs and files, Open modes. Examples: Get Images, View Mode.
4. Logged-in customer, order and cart line
Goal: link print jobs to the customer's account in your shop, and to the order and cart line they belong to.
<!-- Server-rendered for a logged-in customer -->
<script async src="https://app.trondesigner.com/js/website-integration.js" referrerpolicy="origin"
data-td-api="https://app.trondesigner.com/api" data-td-api-key="{API_KEY}"
data-td-customer-identity="{{ user.id }}"
data-td-customer-person="{{ user.name }}"
data-td-customer-company="{{ user.company }}"
data-td-customer-email="{{ user.email }}"></script>// On "Design your print"
window.tronDesigner
.setExactProduct('PFC', undefined, (b) => b.addVariant('10086021'))
.addExactPrinting('front', 'PAD03')
.setPrintJobCustomer(user.id, user.name, user.company, user.email)
.setOrderInfo('Web order', cart.id, cartLine.id) // title, code, item code
.addCustomProperty('cartLineId', cartLine.id)
.open({ mode: 'dialog' });data-td-customer-identitymaps the editor session to the same TronDesigner customer on every browser and device (TronDesigner looks the customer up by this identity). In a single-page app, callawait window.tronDesigner.setCustomer({ customerIdentity: user.id, customerEmail: user.email })after login instead. If the visitor was anonymous until then and the identity is new, the logos and print jobs they created stay with them.setPrintJobCustomerandsetOrderInfostore the data on this print job only.- The session customer is cached in
localStorageundertron-designer-customer. Remove that key when the customer logs out, so the next visitor on the same browser doesn't get their session. - The customer, order and custom properties come back in
event.detailof theprintJobevents and in the REST API.
Read more: Customers and orders. Examples: Session Tracking, Custom Properties.
5. Your own (non-catalog) product
Goal: open the editor for a product that isn't in the TronCloud catalog, with your own codes, names, colors, print area limits and mockup images.
window.tronDesigner.openDesigner({
openMode: 'Create',
dataMode: 'Own',
printJob: {
addProducts: {
model: { modelCode: 'MUG-01', title: 'Custom Ceramic Mug', dimensionsCount: 1, isDimension1Color: true },
variants: [
{ productCode: 'MUG-01-RED', dimension1Title: 'Red', dimension1Colors: ['#FF0000'],
overrides: { productCode: 'MUG-01-RED', productName: 'Ceramic Mug - Red' } },
{ productCode: 'MUG-01-WHITE', dimension1Title: 'White', dimension1Colors: ['#FFFFFF'],
overrides: { productCode: 'MUG-01-WHITE', productName: 'Ceramic Mug - White' } },
],
},
addPrintings: [{
printPositionCode: 'front',
printPositionDisplayName: 'Front',
printTechnologyCode: 'PAD03',
printTechnologyDisplayName: 'Pad print',
colorMode: 'Pantone',
maxColors: 3,
maxWidth: 50,
maxHeight: 50,
ownBackgroundUrls: ['https://cdn.example.com/mockups/mug-front.png'],
}],
customProperties: { pimProductId: 'PIM-98765' },
},
}, { mode: 'dialog' });The display names, colorMode, maxColors, maxWidth, maxHeight and ownBackgroundUrls sit directly on the printing; Own mode doesn't use a supplier. Read more: Data modes, Editor arguments. Example: JSON - Own Product.
6. Server-side follow-up: webhook + REST API
Goal: when a proofreading is generated, your server downloads the PDF and attaches it to the order — no browser involved.
- In Admin Portal → Settings → Webhooks, create an endpoint subscribed to
proofreading.created. - Create a REST API key with Read Access in Settings → API Keys → REST API Keys.
- Handle the webhook (Node.js 18+, reusing
verify()from Webhooks):
const API = 'https://api-v1.trondesigner.com/api';
const auth = { Authorization: `Bearer ${process.env.TD_REST_API_KEY}` };
app.post('/webhooks/trondesigner', express.raw({ type: '*/*' }), async (req, res) => {
if (!verify(req.body, req.headers)) return res.status(401).end();
res.status(204).end(); // acknowledge first; use a queue in production
const { PrintJobGuid, OutputGuid } = JSON.parse(req.body.toString('utf8'));
const printJob = await (await fetch(`${API}/print-jobs/${PrintJobGuid}`, { headers: auth })).json();
const pdf = await fetch(`${API}/print-jobs/${PrintJobGuid}/proofreading/${OutputGuid}`, { headers: auth });
await attachToOrder( // your code
printJob.customer.orderCode,
printJob.customer.orderItemCode,
Buffer.from(await pdf.arrayBuffer()),
);
});Note the casing: the webhook body uses PascalCase (PrintJobGuid), the REST API camelCase (printJob.customer). Read more: Webhooks, REST API. To send customers or operators a signed editor link instead of embedding the editor, see Create an editor link.
See also
- window.tronDesigner — API reference
- Integration concepts
- Integration scenarios (Zendesk)