Printess Editor Integration

The Printess Editor is very simple to integrate into your website in a baseline, out of the box way.

The following chapter will not only teach you how to implement these simple techniques but also dive deeper into ways to make the Printess Integration your very own, utilising parameters and our APIs to build the shop you envision.

Architecture

The Panel-UI is web-component base and very easy to work with for developers. You get full control over the Printess Editor through its API. You can set the initial state of your Editor through the attach parameters, listen to events in with callbacks and manipulate the live state with more API methods.

The Panel-UI also offers much more customization options. You can create themes and remove or move every panel in its position through the Theme Manager.

Getting Started

samples on CodePen

We have created a CodePen profile to provide you with live examples of various use cases.

Printess on codepen.io

The most basic and straightforward integration of the Panel UI will work like this. Printess will automatically determine screen size and device and attach itself in the foreground when loaded.

You can see a simple, working implementation in our CodePen:

Printess - Panel-Ui Integration

Note: If you don’t specify anthing else, the Printess Editor will adapt to the users’ browser language.

The implementation is as simple as this:

<script type="module">
   const printessLoader = await import("https://editor.printess.com/printess-editor/loader.js");
    const printess = await printessLoader.load({
      token: "[your-shop-token]",
      templateName: "[your-template-name]",
      templateVersion: "published",
      basketId: "Some-Unique-Basket-Or-Session-Id",
      addToBasketCallback: (saveToken, thumbnailUrl) =>
        {
          prompt("Savetoken:", saveToken)
        }
    })
</script>

The printessLoader.load() call returns your interfaces into the editor, ui and api.

ui is used to manipulate the UI of the editor, such as closing and reopening it.

api gives you access to template resources, functions and lots of other tools for the editor.

You can find out more on this in the Javascript API chapter and see examples in the Use Cases chapter.

Showing and Hiding the Fullscreen Editor

If you don’t provide a container (see Custom Div Integration below), Printess attaches itself fullscreen. You can still show and hide it programmatically without a custom div, using printess.ui.show() and printess.ui.hide() together with the printess-owned class described in the tip below.

This is handy for a “configure later” flow: keep the editor hidden until the user clicks a button, or hide it again after addToBasketCallback fires instead of navigating away.

<button id="open">JUST SHOW EDITOR</button>

<script type="module">
  const printessLoader = await import("https://editor.printess.com/printess-editor/loader.js");

  const printess = await printessLoader.load({
    token: "[your-shop-token]",
    templateName: "Various Frames",
    templateVersion: "published",
    addToBasketCallback: (token, thumbnailUrl) => {
      prompt("Savetoken: ", token);
      printess.ui.hide();
    },
    backButtonCallback: (token) => {
      printess.ui.hide();
    }
  })

  document.getElementById("open").addEventListener("click", () => {
    printess.ui.show();
  })
</script>

You can also combine this with loadTemplateAndFormFields(templateName, mergeTemplates, formFields, formFieldProperties, translationKey, resetUndoStack) to reset the template to a blank state, or reload a previous save-token, each time the editor is reopened - the last (resetUndoStack) parameter should be true so the user can’t undo back into the previous session’s state:

document.getElementById("reset").addEventListener("click", () => {
  printess.api.loadTemplateAndFormFields("Various Frames", null, null, null, null, true);
  printess.ui.show();
})
Example Code - Full CodePen Source
<h1>Printess Hide & Show Editor</h1>

<div style="height: 100%; background-color: bisque;"></div>

<div class="buttons">
  <button id="open">JUST SHOW EDITOR</button>
  <button id="reset">RESET TEMPLATE & SHOW</button>
  <button id="load">LOAD LAST SAVE-TOKEN & SHOW</button>
</div>

<script type="module">
  let saveToken = "";
  const printessLoader = await import("https://editor.printess.com/printess-editor/loader.js");

  const printess = await printessLoader.load({
    token: "[your-shop-token]",
    templateName: "Various Frames",
    templateVersion: "published",
    addToBasketCallback: (token, thumbnailUrl) => {
      saveToken = token;
      prompt("Savetoken: ", token);
      printess.ui.hide();
    },
    backButtonCallback: (token) => {
      printess.ui.hide();
      document.getElementById("open").scrollIntoView();
    }
  })

  document.getElementById("open").addEventListener("click", () => {
    printess.ui.show();
    printess.ui.show();
  })
  document.getElementById("reset").addEventListener("click", () => {
    printess.api.loadTemplateAndFormFields("Various Frames", null, null, null, null, true);
  })
  document.getElementById("load").addEventListener("click", () => {
    if (saveToken) {
      printess.api.loadTemplateAndFormFields(saveToken, null, null, null, null, true);
    } else {
      alert("Please create a save token first (Click Add to Basket)")
    }
  })
</script>
See fullscreen show and hide without a custom div

Custom Div Integration

You also can provide a <div> for Printess to attach itself to. The following example also shows how to show and hide the editor with avoiding interference on your shop site:

<button id="close">CLOSE</button>
<button id="open">OPEN</button>
<p id="msg" >Click to hide the editor</p>
<div id="printess-editor"  style="">

<script type="module">
  const printessLoader = await import("https://editor.printess.com/printess-editor/loader.js");
  const printess = await printessLoader.load({
    token: "[your-shop-token]",
    templateName: "Baby Photo Book",
    templateVersion: "published",
    addToBasketCallback: (token, thumbnailUrl) => {
      prompt("Savetoken: ", token );
    },
    basketId: "Some-Unique-Basket-Or-Session-Id",
    container: document.getElementById("printess-editor"),
  })

  document.getElementById("close").addEventListener("click", () =>
  {
    printess.ui.hide();
    document.getElementById("printess-editor").style.display = "none";

    document.getElementById("open").style.display = "block";
    document.getElementById("close").style.display = "none";
    document.getElementById("msg").innerText="Click to show the editor";
  })

  document.getElementById("open").addEventListener("click", () =>
  {
    document.getElementById("printess-editor").style.display = "block";
    printess.ui.show();

    document.getElementById("open").style.display = "none";
    document.getElementById("close").style.display = "block";
    document.getElementById("msg").innerText="Click to hide the editor"
  })
</script>

If you want the editor to not claim the entire screen, you will need to style the div that the editor attaches to.

We generally recommend implementing the editor in fullscreen if possible. If you need to have the editor surrounded by other elements, you need to make sure that they behave consistent to the editor, for example by invoking the same function that handles the backButtonCallback when a user navigates away from the editor page.

This is some example CSS for reigning in the editor:

#printess-editor {
  background-color: white;
  position: absolute;
  left: 30px;
  right: 30px;
  top: 60px;
  height: calc(100% - 90px);
  outline: 3px solid red;
  overflow: hidden;
}

While the Printess Editor is displayed fullscreen (no container given), it automatically hides all direct children of <body> that do not carry the class printess-owned, and shows them again when the editor becomes hidden. Give the class printess-owned to elements that should stay visible alongside the editor. This way your elements and the Editor don’t need to use ugly methods such as z-index to figure out what should be visible. Note that this mechanism only applies to the fullscreen integration - when you pass a container as in the example above, no elements are hidden automatically.

Printess - show and hide editor in custom div

Required Attach Parameters

Following are the parameters which are needed to load the Printess Editor, without them the process will fail.

There are more optional attach parameters available - you can use them to personalise your editor integration or achieve more complex workflows.

const printessLoader = await import("https://editor.printess.com/printess-editor/loader.js");

const printessApi = await printessLoader.load({
  token: "[your-shop-token]",
  templateName: "Baby Photo Book",
  templateVersion: "published",
  basketId: "Some-Unique-Basket-Or-Session-Id",
})

token

 token: "[your-shop-token]"

token should be set to a Shop-Token which points to your Printess account. You can retrieve this token once you are logged in (Printess Editor -> Account Menu -> API Tokens). You’ll see 2 different tokens in the dialog. Always use the Shop-Token.

templateName and templateVersion

templateName: 'Baby Photo Book',
templateVersion: "published"

templateName is required and specifies the name of the Template to load. templateName can also take the save-token you received from the back or basket callback and load it directly.

templateVersion can be draft or published. The default is published, which is what you should always use in your live shops.

basketId and shopUserId

basketId: "Some-Unique-Basket-Or-Session-Id"

To allow your customer to upload images and save/load their work - you need to set the basketId.

Alternatively you can set a shopUserId to make Printess store the context of the current customer (user) so when the customer uploads an image it will be stored under the shopUserId. Thus, when the customer returns later they will see all of their previously uploaded images.

Additional Resources

If you want to know more concepts in greater detail, there are additional chapters surrounding the Editor integration.

Page When to consult
Attach Parameters If you want to load additional resources or configure the editor on initial load
Use Cases If you want to add a new Editor functionality, we might have an example of it already
Javascript API If you want to add new Editor functionality, but we do not have an example already
Backend API If you need additional information from the backend or need to implement the file production