Skip to content

Pages rendered on your server

A product page rendered on your server can show the designer’s layout from its first paint: the preview at the photo’s shape, the form with its fields, the strip of views under the preview. The SDK then takes those places over without the page moving. This guide puts that together with the core and the UI.

Your server reads what the designer opens with the client and a secret key, and writes it into the page. The browser then asks Pixonaut for none of it.

const client = createClient({ key: process.env.PIXONAUT_SECRET_KEY, baseUrl: 'https://api.pixonaut.app' });
const data = {
template: await client.templates.get('classic-tshirt@2'),
placement: await client.templates.constraints.get('classic-tshirt@2', { blankId: 'tee', placementId: 'front' }),
blank: {
mockups: await client.blanks.mockups.list('tee'),
variants: await client.blanks.variants.list('tee'),
},
};

The same reads tell your page how large each part is drawn:

  • The preview is its element’s full width, at the shape of the photo it shows first: that photo’s mount.photoSizePx in the blank’s mockups. Without a photo, it is the print’s own shape, widthMm over heightMm of the placement. When the template read’s poweredBy is true, the Powered by Pixonaut mark is drawn in the same element, under the photo: 26 pixels more, its gap included.
  • The form shows the template’s steps and fields, from the template’s form schema, with the print size picker above them when you pass printSizes.
  • The view strip is a row of square photos, 84 pixels each (64 in a row 520 pixels wide or narrower), under a line counting them, one for each view the product is shown in.

Print your own markup in the three elements, sized as the designer will be, with a spinner where the preview goes:

<div id="pixonaut-preview">
<div style="aspect-ratio: 4 / 5"><span class="spinner"></span></div>
</div>
<div id="pixonaut-views"><!-- the views' thumbnails --></div>
<div id="pixonaut-form"><!-- the steps and fields, disabled --></div>

Then hand the core the three elements and what your server read:

import { createDesigner } from 'https://cdn.pixonaut.app/sdk/<version>/pixonaut-core.js';
import { designerUi } from 'https://cdn.pixonaut.app/sdk/<version>/pixonaut-ui.js';
const { template, placement, blank } = JSON.parse(
document.getElementById('pixonaut-data').textContent,
);
const designer = await createDesigner({
previewTarget: '#pixonaut-preview',
formTarget: '#pixonaut-form',
viewsTarget: '#pixonaut-views',
publishableKey: 'pk_…',
apiBase: 'https://api.pixonaut.app',
template,
placement,
blank,
ui: designerUi,
onError: ({ action, error }) => console.error(action, error),
});

createDesigner takes the elements the way mount() does: see The preview and the form apart.

While it starts, the designer draws its parts out of sight and leaves your markup where it is, at its size, spinner and all. The form replaces your form’s markup as soon as it is built from the template, so the customer can start filling it in while the photo downloads and the preview is drawn. Once its preview is drawn, over the photo it will keep, the designer replaces your markup in the preview’s and the view strip’s elements. Each element is replaced on its own: when your markup was the size the designer draws, nothing on the page moves. Once the preview is drawn, on('shown') fires and the designer’s shown() resolves, so anything of your own around the markup can go with it. An element you left empty is drawn into directly. A first preview that is never drawn, such as restored values the template no longer allows, does not keep your spinner for good: after ten seconds the designer takes your markup’s place anyway.

If the mount fails, your markup stays as you printed it, or is put back in the form’s element, onError is called with action: 'mount', and createDesigner rejects with the same error, even if onError throws. Show your own message in its place, or mount again. destroy() before the preview is drawn leaves your markup too.

The preview follows its element’s width for as long as it is mounted: when your columns stack on a narrow screen, or the window is resized, the preview, its photo and the box around the selected layer are laid out at the new width. Size the preview’s element by its width and let its height follow; an element held at a fixed height cuts off what the designer draws.

Questions? Write to [email protected].

Status · Terms of service · Privacy policy · Subprocessors