Skip to content

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):

html
<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.

html
<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.

html
<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.

html
<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.

html
<!-- 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>
js
// 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-identity maps 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, call await 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.
  • setPrintJobCustomer and setOrderInfo store the data on this print job only.
  • The session customer is cached in localStorage under tron-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.detail of the printJob events 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.

js
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.

  1. In Admin Portal → Settings → Webhooks, create an endpoint subscribed to proofreading.created.
  2. Create a REST API key with Read Access in Settings → API Keys → REST API Keys.
  3. Handle the webhook (Node.js 18+, reusing verify() from Webhooks):
js
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 ​

Czech Republic – The Country for the FutureFunded by the European Union – NextGenerationEUThe project was implemented within the The Country for the Future programme of the Ministry of Industry and Trade and co-financed by the European Union under NextGenerationEU.Support · Examples

Czech Republic – The Country for the FutureFunded by the European Union – NextGenerationEUThe project was implemented within the The Country for the Future programme of the Ministry of Industry and Trade and co-financed by the European Union under NextGenerationEU.Support · Examples