Examples

These examples extend the hosted quickstart. Every method on the mounted drawing API is asynchronous because work crosses the isolated frame boundary.

Table of Contents

Minimal Editor

The smallest complete integration is one fetch and three lines of browser code. Your server exchanges its project API key for a one-time session, and your browser gives only that session to the versioned SketchAPI client. There is no package install or local-runtime fallback:

import { Sketchpad } from 'https://sketchapi.com/sdk/v1/sketchapi.js'

const session = await (await fetch('/api/sketchapi/session', { method: 'POST' })).json()
const api = await new Sketchpad({ session }).mount(document.querySelector('#sketchpad'))
await api.layer.create({ fill: '#2f6fed', height: 240, type: 'rectangle', width: 320 })

The quickstart walks through the server half and the required host element height.

Cancellation and Errors

Abort mounting when its host view is removed:

const controller = new AbortController()

try {
	const api = await sketchpad.mount(container, {
		signal: controller.signal
	})
	await api.runtime.ready()
} catch (error) {
	if (error.name !== 'AbortError') {
		console.error(error.code, error.message)
	}
}

controller.abort()
sketchpad.destroy()

HostedSketchAPIError exposes a machine-readable code for transport and remote failures. Session creation errors use the control plane’s JSON error envelope. Do not retry an already consumed session; request a new one.

Hosted Browser Files

The hosted frame may expose an instance-bound native document library through sketchpad.files after mounting:

await sketchpad.mount(container)

const files = sketchpad.files
if (files) {
	const stored = await files.save({ name: 'Cover artwork' })
	await files.rename(stored.id, 'Final cover artwork')
	const recent = await files.list()
	console.log(recent)
}

The library is browser-backed storage owned by the hosted frame. It is not your customer’s account storage or a cloud-sync contract. Use api.save to obtain portable output when your application needs to upload or persist artwork in its own system.

Multiple Instances

Mint a separate session for every editor. One-time sessions cannot be reused by two mounts:

const [firstSession, secondSession] = await Promise.all([createSession(), createSession()])

const first = new Sketchpad({ session: firstSession })
const second = new Sketchpad({ session: secondSession })

const [firstApi, secondApi] = await Promise.all([first.mount(firstContainer), second.mount(secondContainer)])

await firstApi.tool?.use('paintbrush')
await secondApi.tool?.use('tileBrush')

first.destroy()
second.destroy()

Each instance owns its frame, documents, API, events, input, and teardown.

Events

Hosted events contain data only. Keep the unsubscribe function or bind the subscription to an abort signal:

const controller = new AbortController()

api.events.on(
	'document:change',
	(event) => {
		console.log(event.type, event.detail)
	},
	{ signal: controller.signal }
)

controller.abort()

Use api.events.names to discover the event names offered by the connected runtime.

Products Built on SketchAPI

PikaPressGo uses the same hosted lifecycle for a focused print-product editor. Product Customizer mints sessions through the Commerce server while Commerce continues to own its customer, artwork, order, and fulfillment records. Neither consumer receives the private editor runtime.

Open Playground to try the versioned browser client, or read the generated API reference for exact namespace methods.