Skip to content

Loading the integration script ​

Every website integration starts with one <script> tag. This page lists the attributes the tag accepts, explains what the script does while it initializes, and shows how to wait for it and how to handle a failed initialization.

Add the script tag ​

Put this tag in the <head> of every page that opens the editor (or at the end of <body>):

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>
  • src — the only public URL of the script. (Older documentation mentions a script URL on the integration.trondesigner.com host; that URL doesn't exist.)
  • async — recommended. The script doesn't block rendering, but window.tronDesigner only exists once the script has run (see Wait until the script is ready).
  • referrerpolicy="origin" — recommended. When the browser loads the script it sends only your site's origin, not the full page URL.
  • Load it as a classic script. Don't use type="module" and don't bundle the file into your own code: the script reads its configuration from its own <script> element (document.currentScript).
  • You can also create the tag from JavaScript, for example in a single-page application. Set all data-td-* attributes before you append the element to the document.
Environmentsrcdata-td-api
Productionhttps://app.trondesigner.com/js/website-integration.jshttps://app.trondesigner.com/api
Developmenthttps://app-dev.trondesigner.com/js/website-integration.jshttps://app-dev.trondesigner.com/api

Use a separate API key for each environment. Keys are created in the matching Admin Portal (portal.trondesigner.com / portal-dev.trondesigner.com).

Script tag attributes ​

The script tag accepts 18 data-td-* attributes. Only the first two are required. Callback attributes take the name of a global function (see Callback functions).

Required

AttributeValue
data-td-api-keyYour website integration API key.
data-td-apiScript API URL: https://app.trondesigner.com/api. A trailing / is removed.

Customer — link print jobs to a customer account in your system (details in Customers and orders):

AttributeValue
data-td-customer-identityYour stable ID of the logged-in customer. When set, the script looks up the TronDesigner customer with this identity (or creates one), so the same customer is recognized on any device.
data-td-customer-personCustomer's name. Used only together with data-td-customer-identity.
data-td-customer-companyCustomer's company. Used only together with data-td-customer-identity.
data-td-customer-emailCustomer's e-mail. Used only together with data-td-customer-identity.

Behavior

AttributeValue
data-td-languageTwo-letter ISO 639-1 code (for example en, de) of the editor's default UI language. A language the customer picked in the editor earlier takes precedence. Without it, the editor uses the browser language.
data-td-log-leveldebug, info, warn (default) or error. See Debugging and error handling.
data-td-monitored-element-idid of an element whose content changes after page load. Action elements added inside it are registered automatically. See HTML data attributes.

Callbacks — see Events and callbacks for payloads:

AttributeCalled when
data-td-script-initialized-callbackInitialization succeeded. No arguments.
data-td-script-init-failed-callbackInitialization failed. Receives an Error (or a string).
data-td-print-job-created-callbackA print job was created.
data-td-print-job-updated-callbackAn existing print job was saved.
data-td-logo-created-callbackA logo was uploaded.
data-td-logo-updated-callbackA logo was changed.
data-td-logo-deleted-callbackA logo was deleted.
data-td-text-created-callbackA text was created.
data-td-proofreading-created-callbackA proofreading PDF was generated.

All attributes with formats and examples: Data attributes reference and ScriptElementDataAttributesNames.

Callback functions ​

The script looks the function up as a property of window by its name. Define it with a function declaration in a classic script, or assign it to window explicitly:

js
function onTronDesignerReady() { /* … */ }        // works
window.onTronDesignerReady = () => { /* … */ };  // works
const onTronDesignerReady = () => { /* … */ };   // doesn't work: not a property of window

Functions declared inside <script type="module"> aren't global either. If the function isn't found, the script logs Global callback function '…' not found (or … is not a function) to the console.

What happens during initialization ​

  1. The script runs and creates window.tronDesigner right away. At this point you can't open the editor yet.
  2. It waits until the page has fully loaded (document.readyState is complete, the same moment as the window load event).
  3. It reads the data-td-* attributes of its <script> element and registers the callback functions.
  4. It initializes the customer by calling the API. The API checks the API key, the license and the page's domain. The customer GUID is stored in the browser's localStorage under the key tron-designer-customer, so a returning visitor keeps the same TronDesigner customer.
  5. It loads the editor — the <trondesigner-editor> web component — from {data-td-api}/resources/trondesigner-editor.js.
  6. It scans the page for elements with data-td-action or data-td-options and attaches click handlers. It also starts logo visualizations (if your license includes them) and watches the element set in data-td-monitored-element-id.
  7. It reports success: getInitialized() returns true, the promise from getInitializing() resolves, and the data-td-script-initialized-callback function is called.

If step 3, 4 or 5 fails — including an editor script that can't be loaded in step 5 (for example a 404, or a Content Security Policy that blocks it) — the script reports the failure instead (see Handle initialization failures) and the editor can't be opened on this page load.

Wait until the script is ready ​

Pick the option that fits your code:

  • data-td-script-initialized-callback — simplest; the function runs once, after step 7.
  • getInitializing() — a promise for code that runs later. It resolves after step 7 and rejects when initialization fails, so use it with try … catch. Because the script is async, window.tronDesigner may not exist yet when your own inline scripts run; it does exist after the window load event.
  • getInitialized() — a synchronous check, for example at the start of a click handler.

Open the editor only once one of these tells you the script is ready. Called earlier (or after a failed initialization), openDesigner(), open() and the other methods that open the editor log an error and do nothing.

js
window.addEventListener('load', async () => {
  try {
    await window.tronDesigner.getInitializing();
    // The editor can be opened now.
  } catch (error) {
    // Initialization failed: hide your design buttons (see below)
    console.error('TronDesigner is unavailable:', error?.cause ?? error?.message ?? error);
  }
});

function onDesignClick() {
  if (!window.tronDesigner?.getInitialized()) return; // not ready yet, or initialization failed
  window.tronDesigner
    .setExactProduct('PFC', undefined, (product) => product.addVariant('10086021'))
    .addExactPrinting('front', 'PAD03')
    .open({ mode: 'dialog' });
}

An exception thrown inside your data-td-script-initialized-callback is logged to the console and doesn't change the result of getInitializing().

Handle initialization failures ​

Initialization fails when the API rejects the request (wrong key, domain not allowed, license), when data-td-api-key / data-td-api is missing, when the browser has no localStorage, or when the editor script can't be loaded (404, blocked by a Content Security Policy). The script then:

  • rejects the getInitializing() promise with the error (if nobody waits for the promise, this doesn't produce an "unhandled rejection" error),
  • calls the function named in data-td-script-init-failed-callback with the error (an exception inside that function is logged and changes nothing), and
  • dispatches a userInitFailed CustomEvent on its own <script> element, with the error in event.detail. The event doesn't bubble, so listen on the script element itself.

Use whichever fits your code; all three get the same error.

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}"
  data-td-script-init-failed-callback="onTronDesignerInitFailed"
></script>

<script>
  function onTronDesignerInitFailed(error) {
    // error.cause holds the server's reason, e.g. "API key is invalid: Domain shop.example.com is not allowed"
    console.error('TronDesigner is unavailable:', error?.cause ?? error?.message ?? error);
    document.querySelectorAll('.design-button').forEach((button) => (button.hidden = true));
  }
</script>
html
<script
  async
  id="trondesigner-script"
  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>

<script>
  document.getElementById('trondesigner-script').addEventListener('userInitFailed', (event) => {
    const error = event.detail;
    console.error('TronDesigner is unavailable:', error?.cause ?? error?.message ?? error);
  });
</script>

When the API rejects the request, the error message is ApiCaller::call: failed - response status 401 and error.cause contains the reason:

error.causeWhat to do
API key is invalid: Provided API key is not validCheck data-td-api-key.
API key is invalid: API key is disabledEnable the key in Settings → API Keys.
API key is invalid: Domain … is not allowedAdd the page's host name to the key's allowed domains.
API key is invalid: Web Integration feature for TronDesigner license is required for integrations outside of PromoTron platform!Your license needs the Web Integration feature.
API key is invalid: TronDesigner instance is not active / … is expiredContact PromoTron support.
API key is invalid: Missing referer in headerThe browser sent neither a Referer nor an Origin header.

If data-td-api-key or data-td-api is missing, the console shows initialization failed - cannot receive API key (or API url) and the callback receives an error with that message. If the editor script can't be loaded, the error message is initialize: cannot load the editor (…/resources/trondesigner-editor.js).

Allowed domains ​

Each website integration API key has a list of allowed domains (Admin Portal → Settings → API Keys → Website Integration API Keys). The API takes the host name from the Referer header of each request (or from Origin when there is no Referer) and accepts the request when the host name is one of the entries or a subdomain of one.

  • Enter host names only: shop.example.com, example.com, localhost. No https://, port or path.
  • example.com also matches shop.example.com and www.example.com, but not myexample.com.
  • Ports are ignored: localhost covers http://localhost:3000 and http://localhost:8080.
  • Pages opened from disk (file://) have no host name and are always rejected.

The key is visible in your page source; allowed domains are what stop other sites from using it. Never put a REST API key in a web page.

WARNING

Don't leave localhost on a production key. Every browser can open a page on localhost, so a key that allows it can be used by anyone who copies it from your page source — on your license, creating logos and print jobs in your instance. Use a separate key for development and testing (with localhost, a staging domain, …) and keep only your live domains on the production key. Remove localhost once the integration is finished.

For the same reason, don't allow shared hosting domains such as csb.app, vercel.app or netlify.app: anyone can publish a site under them. Allow your exact subdomain instead (my-shop.vercel.app).

Content Security Policy ​

If your site sends a Content-Security-Policy header, allow at least:

  • script-src https://app.trondesigner.com — the integration script and the editor module,
  • connect-src https://app.trondesigner.com — API requests,
  • style-src https://app.trondesigner.com 'unsafe-inline' — the editor's stylesheets, and a small <style> element the script adds to <head>,
  • font-src https://app.trondesigner.com — the editor's icon font,
  • the host of your ownCssVariablesUrl in style-src, if you use it (see Styling the editor).

The editor also loads images and other assets while it runs. Test with the browser console open and add any hosts it reports as blocked.

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