Shopify Integration

This document describes how to integrate the Printess Editor into your shopify theme. This is done by uploading a set of javascript files to the themes assets, modifying some of the themes liquid files and adding new product meta data properties. To integrate the editor, you will need some basic skill in web development technologies (Html / Javascript). This documentation is written using the shopify standard theme “Horizon”. In case another theme is used, it is required to find out where the “Add to basket” button is located and the render code for each cart item (Horizon: cart-products.liquid) and modify these to integrate our changes. The theme modifications need to be done every time you want to update or switch your theme.

To prevent unnecessary reintegrations, make sure that the theme is the final decision and check that the theme has the most recent version.

Adding Printess to your shopify theme

Printess is integrated into shopify by adding buttons that lead to the customisation of your products. This is done through the shopify theme. In order for this to work, you will need to download two files from our

github page for the shopify integration

The two files in question are printess-cart.liquid and printess-init.liquid.

Once you have grabbed these two files, navigate to the shopify Theme editor, by going to your shopify dashboard, selecting Online Store -> Themes. On the very top you can see your current theme, in our example it’s shopify’s default theme “Dawn”. Here you have to click the button with 3 dots, which opens a context menu where you can click Edit Code.

Navigating to the theme editor

On the left hand side of the editor window you will see a directory structure. Find the directory snippets and copy the downloaded files into it, by dragging & dropping them from your PCs file explorer.

Inserting .liquid files

After uploading these files, you need to load the Printess editor. For this, navigate to the layout directory of the theme and open theme.liquid. There you have to add the Printess loading code inside the “head” tag.

    {% render 'printess-init',
      cssProductContainerSelector: "div.product",
      cssAddToBasketButtonSelector: 'button[type="submit"][name="add"]',
      cssCartItemSelector: "tr.cart-item"
    %}

Loading Printess in your theme

Note that the CSS selectors (such as cssProductContainerSelector) are not needed if you use the shopify default theme and PanelUI, but for other themes or more complex integrations.

In order to be able to edit a product after it was put into the shopping cart, we need to add a button that will take the item back into the Printess editor. This can be done in the cart-products.liquid file in the snippets directory.

In our example, we have put the button directly underneath the preview image of the item, but with some knowledge in HTML and web development, you can place it virtually anywhere in your cart.

Loading Printess in your theme

As you can see in the image above, all you need is to add the following code:

{% render 'printess-cart', cartItem: item %}

You need to pass the current shopping cart item to the button, but it may not be called item if you don’t use the default theme. Look around for other usages of the item in order to find the correct name. In the picture above, one such usage is highlighted with an arrow!

Shopify Settings

You need to deactivate the Accelerated Buy Buttons, otherwise your customers may buy unedited items without noticing! Simply go to your store, click Edit Theme and switch to the Default Product view. Here you select the “Buy buttons”.

Navigate to Buy buttons

In the menu that opens, you need to deactivate the Dynamic checkout buttons.

Deactivate Dynamic buttons

Installing the Printess App to shopify

After you are done customizing the theme of your shopify to use Printess, you can install the Printess app in your shopify store.

Printess App on the shopify App store

On this page, simply click the Install button and after confirming your intent on the next page, the installer will take care of the rest. Installing Printess Installing Printess confirmation

After installing you will be redirected to your Printess Admin Portal, ready to inspect and further configure your shopify integration.

Shop Integration setup

This page will show you the general setup for your shop as well as the products listed in it.

The Setup tab contains general settings for your Shopify integration. An important one is the Webhook setup, which allows your customers orders to be sent to production. In your shopify administration, you have to create a new order created web hook where you provide the url that is displayed in the Printess settings of your shop integration:

Shopify Webhook URL

After you added that web hook in shopify, shopify is displaying the webhook signing key on the bottom of the list of all registered web hooks. You have to take this key and copy it into the Printess settings under “Webhook Signing Key” just underneath the Webhook URL.

Without this, you will not see any produced PDF/Image files inside the Printess Account Portal.

The Products tab will show you all products in your shopify shop that have the Printess Tag. Clicking any product will expand it and give you more options, such as linking it to a Printess template or setting up other templates to merge into your base template on load. You need to link a template to your product to load Printess in your shop. Additionally you can select to use the SlimUI for a product here, if you want to use our more lightweight UI.

This view shows all products from your Shopify store, which have the Printess tag, which means in order to link a product to a Printess template, you need to create the product in Shopify first.

Products setup

The thumbnail of your product is loaded from shopify, if you want to update it, you need to do it on the shopify product page.

The pink wand next to a product thumbnail indicates that this product is set up with a Printess template and ready to be customised in your shop. If the wand is missing, you might have to check if everything is in order!

Congratulations! If you have reached this point, you should be all set up to use Printess in shopify! If you open a Printess-configured product now, you should see a “Design now” button instead of “Add to Cart”.

Printess succeddfully integrated

Clicking it will take you to the Printess editor for customisation, and once your product looks just right, you can use the Printess “Add to Basket”-Button in order to place it in your shopify cart.

Allowing users to save and load

If your customers need to save their work and return to it later, you need to activate “Show sign-in links” in your shop settings (Shop Settings > Customer accounts).

Activate Show Sign-in Links

In your theme code, inside the theme.liquid file, you need to add the line supportsSaving: true, to the Printess initialization:

{% render 'printess-init',
  supportsSaving: true,
  cssProductContainerSelector: "div.product",
  cssAddToBasketButtonSelector: 'button[type="submit"][name="add"]'
%}

Then you need to add a menu to your customers user profile. In your shop admin page, navigate to Content > Menus and select the “Customer account main menu”. Here ypu can add a new entry and give it a name such as Saved Projects, and select a link. Inside there you can select apps, which includes the Printess app, and clicking it will configure the menu automatically.

Menu settings Selecting the Printess menu

After doing this, you have to edit your store theme with the shopify theme editor. Inside the editor, you need to select Checkout and customer accounts in the top bar, and after that opens, in the new top bar, select Profile.

Checkout and customer accounts Profile View

This opens a sidebar, in which you need to select the Sections view (marked in red), where the option Header should be highlighted, because it is missing a link.

Profile Header settings

Click it to open another sidebar, in which you can add the missing link by clicking Add page.

Add link to header

Connecting Product Variants with Form Fields

The Printess shopify integration automatically forwards Shopify product variant options to the editor. Imagine, the product has a Color variant option with the values red, green, blue.

Screenshot of the Color Shopify variant option

The Printess template needs to have a form field called Color that has the exact same option values as the Shopify option. You can also use form fields that have the same label as the product variant in you shopify setup, as well as options that match the form field value labels. Form field name and the options’ value will take precedent over their label.

Screenshot of the Printess Color form field configuration

Casing is important for the automatic form field mapping. Make sure that the form field name and option values exactly match the Shopify option name and values. The name of the formfield must also match the name of the HTML input element in your product page. If this is not possible with your shop theme, please contact our support team.

In case the end customer is allowed to change these values during the design editing inside the editor, make sure that value changes done inside the editor are fed back to the shopify shop, ensure that the price relevant option is activated inside the form field configuration.

Screenshot of the Printess price relevant form field setting

Printess form field names are restricted to certain characters and do not support white spaces. Sometimes, form field names are already predifined (the DOCUMENT_SIZE form field for eaxample) by the printess editor. In many cases you need to have the ability to freely name your shopify variant options and you definitley do not want to name them DOCUMENT_SIZE. To account for this, instead of mapping your shopify options to Printess form field names, it is also possible to map against the labels of the form field. So instead of Color create a Shopify product variant option called “Cover Color” and rename the variant option values to uppercase characters: Red, Green, Blue. On the Printess template form field modify the labels accordingly:

Screenshot of the Printess form field label configuration

To prevent issues during the automated mapping, you need to ensure on the Printess formfield configuration, that the labels do not match the form field name / values, a shopify option name / value that can not be mapped uniquely to either the name OR the label will cause unforseen issues when trying to write values back to Shopify.

Default Formfield values at production time

The shopify integration is writing additional information about the order and its contents to the template at the time of production. Order properties like the order id, the order name (the display name of the order) or the order recipient name are written into form fields named orderId, orderName, itemQuantity, itemSku etc. In case you want to use one of these values inside your documents, you have to make sure that the template has form fields with specific names. These values will then be set at the time of the PDF creation. The predefined form field names are:

itemQuantity
itemSku
orderId
orderName
lineItemId

CustomerFirstName
CustomerLastName
CustomerName
CustomerAddress1
CustomerAddress2
CustomerCity
CustomerCompany
CustomerCountry
CustomerCountryCode
CustomerPhone
CustomerProvince
CustomerProvinceCode
CustomerZip

ShippingFirstName
ShippingLastName
ShippingName
ShippingAddress1
ShippingAddress2
ShippingCity
ShippingCompany
ShippingCountry
ShippingCountryCode
ShippingPhone
ShippingProvince
ShippingProvinceCode
ShippingZip

BillingFirstName
BillingLastName
BillingName
BillingAddress1
BillingAddress2
BillingCity
BillingCompany
BillingCountry
BillingCountryCode
BillingPhone
BillingProvince
BillingProvinceCode
BillingZip

The Customer- prefixed values representing available information of the shop customer that ordered the product. The Shipping- prefixed values represent the shipping destination (Address) that was provided by the customer. The Billing- prefixed values represent the personal information of the invoice recipient. In case your printer requires an additional page in your document that contains the recipients name / address and the item sku, quantity for content validation at the time of packaging, you could create these 5 form fields

itemQuantity
itemSku
ShippingName
ShippingAddress1
ShippingAddress2
ShippingZip
ShippingCity

that can then be used for example as variables inside text items on your template’s documents.

CustomerName, ShippingName, BillingName are values automatically created by the Printess backend and consist of a combination of the first and the last name (${Firstname} ${LastName}).

Allowed characters for form field names are pretty limited. For example, Spaces, periods, hyphen etc are not allowed. Therefore, in some rare cases (Using of data table, custom integrations) it is not possible to create a form field that has the exact same name that would be required to pull in a specific value into your template. In these cases, you will need to provide a form field mapping that mapps the names used by the shopify integration to the corresponding form field name. The Form field mapping is a simple dictionary lookup with key and value pairs where the keys are the extern names (like CustomerName or ShippingCountry) and the values are the names of the corresponding Printess template form field names. To make this configuration readable by our system, it must be JSON formated.

Example:

{
  "ShippingName": "Recipient",
  "ShippingAddress1": "Street",
  "ShippingAddress2": "Apartment",
  "ShippingZip": "PostalCode",
  "ShippingCity": "City"
}

The above example maps the recipient address that is provided by the Printess backend to a printess tempalte that contains the following form fields: “Recipient”, “Street”, “Apartment”, “PostalCode”, “City”. In this example, mappings would be obsolote by using the same form field names as the names provided by the printess backend. However in some customer specific integrations like Etsy or Amazon the mappings become mandatory in case the incoming variales contain space or other non numeric characters (Rule of thumb a-Z and 0-9 are allowed as long as the first character is alphanumeric and not a number). If your integration for example writes the following variables:

Customer First Name
Customer Last Name
Customer Address1
Customer Address2
Customer Zip
Customer City

These variable names can not be represented as form field names and therefore must be mapped. One example mapping could be:

{
  "Customer First Name": "Firstname",
  "Customer Last Name": "Lastname",
  "Customer Address1": "Address1",
  "Customer Address2": "Address2",
  "Customer Zip": "Zip",
  "Customer City": "City"
}

Your custom integration might have specific variables. For Amazon integrations for example, all personalization values are prefixed with properties. Like propertiesSurname and propertiesName. In these cases, no mapping is required. However, in case the amazon personalization value contains spaces like “Nick name” or the resulting “propertiesNick name” the mapping gets mandatory.

Another scenario where mappings becomes mandatory is using a data table form field. Lets assume a form field table is ised with the following columns: Firstname, Lastname, Address1, Address2, Zip and City a mapping is required that tells the printess backend to write into these table columns. This is done by prefixing all values with form.data.. So instead of Firstname we have to provide the value form.data.Firstname:

{
  "CustomerFirstName": "form.data.Firstname",
  "CustomerLastName": "form.data.Lastname",
  "CustomerAddress1": "form.data.Address1",
  "CustomerAddress2": "form.data.Address2",
  "CustomerZip": "form.data.Zip",
  "CustomerCity": "form.data.City"
}

or in case of above mentioned properties prefixed values:

{
  "propertiesName": "form.data.Name",
  "propertiesSurname": "form.data.Surname",
}

or with spaces in the keys like “propertiesFirst Name”:

{
  "propertiesFirst Name": "form.data.Firstname",
  "propertiesLast Name": "form.data.Lastname",
}

To provide these mappings to the printess backend, a new shopify product metafield is required. (See Creation of required product meta fields). Use Formfield Mappings as display name (or any other) and printess.formFieldMappings as namespace and key. The description could be Json object containing template mappings for printess. Choose Single line text as data type. Now, every product in your shopify configuration has a new field Formfield Mappings where the mapping can be provided. In order to provide the mapping to this field, the json object needs to be reformatted into one line. Instead of

{
  "CustomerFirstName": "form.data.Firstname",
  "CustomerLastName": "form.data.Lastname",
  "CustomerAddress1": "form.data.Address1",
  "CustomerAddress2": "form.data.Address2",
  "CustomerZip": "form.data.Zip",
  "CustomerCity": "form.data.City"
}

all new line needs to be removed and everything brought into one line:

{"CustomerFirstName": "form.data.Firstname", "CustomerLastName": "form.data.Lastname", "CustomerAddress1": "form.data.Address1", "CustomerAddress2": "form.data.Address2", "CustomerZip": "form.data.Zip","CustomerCity": "form.data.City"}

This can then be provided to your product configuration.

Dropshipping with shopify

You can automatically send your shopify orders to a production partner through the Printess Dropshipping settings.

For this you can set a dropshipping ID in your product’s metafields:

Dropshipping ID metafield

If you want to define the dropshipping IDs in Printess, simply put 0 as the ID in shopify and the Printess dropshipping integration will instead use the one specified in your product template.

CSS selectors needed for any integration

If you use a theme other than “Dawn”, maybe even a custom one fully made by yourself, you may need to access some elements, such as the “Add to Basket”-Button through CSS selectors.

Our plugin has reasonable defaults and fallbacks which work for the majority of themes, which means most things should work out of the box. If your shop does work with Printess out of the box, the following CSS selectors are probably what you need to fix.

If you find a CSS selector in an official Shopify theme that isn’t part of our default configuration, feel free to send it our way so we can add it to our plugin and improve our seamless integration!

Some of these selectors will be needed no matter which integration you choose and will be listed directly in this chapter. If you intend to use the SlimUI, the next chapter contains some more selectors that you might need.

We have collected some of the important selectors for you, but if your theme is entirely made by you or a contractor of yours, chances are high that these will not apply to your integration. In that case you will have to find out the relevant selectors by browsing the code of your theme.

These selectors are specified in the Printess loading component inside the head of your theme:

  {% render 'printess-init',
    cssProductContainerSelector: "div.product",
    cssAddToBasketButtonSelector: 'button[type="submit"][name="add"]',
    cssCartItemSelector: "tr.cart-item",
  %}

The selector for one item in the shopify cart is cssCartItemSelector: ".cart-items__table-row", it is the element in the DOM closest to root, that contains an entire item in the shopping cart view.

CSS selectors needed for the SlimUI

The SlimUI is a light weight version of the Printess Editor, but much more deeply integrated into your Shopify shop. In order for this deep integration to work, it needs to alter and anchor itself to some more elements in the Shopify UI.

Any product you want to customize using the SlimUI needs to have at least one picture.

  {% render 'printess-init',
    cssProductInfoSelector: ".product__info-wrapper",
    cssProductMediaSelector: "media-gallery>slider-component",
    cssImageSelector: ".product__media>img",
    cssPriceTextSelector: "span.price-item",
    cssProductFormSelector: "form.installment",
    cssProgressIndicatorSelector: "div.loading__spinner",
    cssQuantityInputSelector: "input.quantitiy__input",
    cssProductThumbnailImageSelector: ".card__media img",
    cssProductLargePreviewImagesSelector: "{GLOBAL}.product-media-modal__content>img",
    cssCartItemLinkSelector: "a.cart-item__link",
    cssCartItemImageSelector: "img.cart-item__image",
    cssCartItemQuantitySelector: "quantity-input.cart-quantity>input",
    cssProductIdSelector: 'input[name="product-id"]',
    cssCartItemListSelector: "table.cart-items",
    cssVariantSwitchSelector: "variant-selects",
    formInsertPosition: 2,
  %}

cssProductInfoSelector and cssProductMediaSelector are the two parts of your product page, one containing all the product information, the other your product media. Importantly, cssProductInfoSelector must be a direct child of cssProductContainerSelector.

cssVariantSwitchSelector is needed in order to hide the product variant selection of shopify in favor of the Printess form. In order for this to be correctly set up you also need to make sure the product variants in shopify match the form fields (name and values) in your printess configuration and the name of the HTML input element mapped to the property. Additionally, the Printess form fields must be set as price relevant.

The formInsertPosition is a fallback for placing the SlimUI form, in case the cssVariantSwitchSelector cannot be found. It’s number is the position where the form should be displayed in the product’s info wrapper.

Removing your shopify integration

If you want to remove your shopify integration, you can do this with two easy steps.

You need to remove the shopify integration from your Account Portal by selecting the integration you want to remove and clicking the “Delete”-Button.

Delete shopify integration from Account Portal

You also need to uninstall the Printess App from your shopify shop. Navigate to the app settings, where you can see all apps of your shop and find the Printess app. The 3 dots open a context menu which allows you to “Uninstall” the app.

Uninstall the Printess app

You need to take both of these actions to cleanly remove Printess from your shopify and vice versa, otherwise a reinstallation might fail!