Skip to content

Export Module (Export)

The Export module encapsulates download and "Open in xTool Studio" capabilities. It does not handle billing. Billing is managed by the billing module and used in combination via withBilling().

API List

MethodReturn ValueDescription
sdk.export.register(provider)voidRegisters the export capability provider (call once during initialization)
sdk.export.download(options?)Promise<ExportDownloadResult>Downloads the image locally
sdk.export.openInStudio(source? | options?)Promise<ExportOpenInStudioResult>Opens in xTool Studio

Registering an Export Provider

Important

You must call register() before using download() or openInStudio(); otherwise, an error will be thrown.

The provider must implement at least one of getExportData or getExportCanvas.

The SDK supports two provider methods (priority: getExportData > getExportCanvas):

  • getExportData — Flexible approach for non-canvas scenarios (SVG editors, DOM-based renderers, pure data generators).
  • getExportCanvas — Traditional approach, returns an HTMLCanvasElement directly.

Example: Canvas-based (traditional)

typescript
sdk.export.register({
  getExportCanvas: (purpose) => {
    // purpose: 'download' | 'studio' | 'cover'
    return document.getElementById('outputCanvas') as HTMLCanvasElement
  },
  getFileName: (purpose) => `my-design-${Date.now()}.png`,
})

Example: SVG / non-canvas (flexible)

typescript
sdk.export.register({
  getExportData: (purpose, format) => {
    if (format === 'svg') {
      const svgEl = document.getElementById('svgCanvas')
      return { type: 'svg', svgString: new XMLSerializer().serializeToString(svgEl) }
    }
    // For bitmap formats, render SVG to a temporary canvas
    const canvas = renderSvgToCanvas()
    return { type: 'canvas', canvas }
  },
  getFileName: (purpose) => `my-design-${Date.now()}.svg`,
})

ExportProvider Interface

typescript
interface ExportProvider {
  getExportData?: (
    purpose: ExportPurpose,
    format: ExportFormat,
  ) => ExportData | Promise<ExportData | null> | null

  getExportCanvas?: (
    purpose: ExportPurpose,
  ) => HTMLCanvasElement | Promise<HTMLCanvasElement | null> | null

  getFileName?: (purpose: ExportPurpose) => string
}

type ExportPurpose = 'download' | 'studio' | 'cover'
type ExportFormat = 'png' | 'jpeg' | 'webp' | 'svg'

type ExportData =
  | { type: 'canvas'; canvas: HTMLCanvasElement }
  | { type: 'blob'; blob: Blob }
  | { type: 'dataUrl'; dataUrl: string }
  | { type: 'url'; url: string }
  | { type: 'svg'; svgString: string }

Resolution order:

  1. If getExportData is implemented and returns a non-null value, use it.
  2. Otherwise, fall back to getExportCanvas.
  3. If neither returns data, an SdkError is thrown.

Download to Local

Supports png, jpeg, webp, and svg formats.

typescript
// Download as PNG (default)
const result = await sdk.export.download({
  fileName: 'my-design.png',
  format: 'png',
})

// Download as JPEG with quality
await sdk.export.download({
  fileName: 'my-design.jpg',
  format: 'jpeg',
  quality: 0.85,
})

// Download as SVG (requires getExportData to return SVG data)
await sdk.export.download({
  fileName: 'my-design.svg',
  format: 'svg',
})

SVG Export

Exporting SVG from a plain HTMLCanvasElement is not possible. If your provider only implements getExportCanvas, requesting format: 'svg' will throw an error.

To support SVG export, implement getExportData and return { type: 'svg', svgString: '...' }.

Internal flow:

  1. Call getExportData(purpose, format) if available.
  2. Fall back to getExportCanvas(purpose)canvas.toBlob(mimeType, quality).
  3. Create <a> tag to trigger browser download → Cleanup.

Open in xTool Studio

openInStudio() imports content into xTool Studio.

It supports two calling conventions (backward compatible):

typescript
// Original: pass source directly
await sdk.export.openInStudio('https://example.com/design.png')
await sdk.export.openInStudio(myBlob)

// New: pass options object with format control
await sdk.export.openInStudio({ format: 'svg' })
await sdk.export.openInStudio({ source: myBlob, format: 'png' })

// No arguments: uses provider to generate PNG by default
await sdk.export.openInStudio()

ExportOpenInStudioOptions

typescript
interface ExportOpenInStudioOptions {
  source?: ExportOpenInStudioSource  // URL / data URL / Blob / File
  format?: ExportFormat              // default 'png'
}

When source is provided, it is used directly (same as before). When source is omitted, the SDK calls the provider's getExportData or getExportCanvas with the specified format to produce the data.

Important

Users must log in via the Auth module before calling openInStudio().

This is because the upload process relies on the token obtained after login; if the user is not logged in, the import to xTool Studio cannot be completed successfully.

typescript
// Default: PNG via provider
const result = await sdk.export.openInStudio()
// { success: true }

// Pass remote URL directly to Studio
await sdk.export.openInStudio('https://example.com/design.png')

// SVG format: provider produces SVG, Studio receives type 'SVG'
await sdk.export.openInStudio({ format: 'svg' })

// Explicit source + format
await sdk.export.openInStudio({ source: myFile, format: 'png' })

Internal flow:

  1. If source is an HTTP URL, pass it directly to Studio.
  2. If source is image data (data URL / Blob / File), upload to OSS first.
  3. If no source, call provider with the specified format → produce Blob → upload to OSS.
  4. SVG format uses type: 'SVG' in the Studio protocol; other formats use type: '2D'.
  5. When running in an iframe, notify the parent page via postMessage.
  6. Fallback: Open a new window to display the image.

MIT Licensed