Generate finished designs from templates by loading, populating variables, and exporting to images, PDFs, or videos programmatically.

Template generation transforms templates into finished designs by populating data and exporting to output formats. Load templates with engine.scene.loadFromURL(), set variables with engine.variable.setString(), and export with engine.block.export(). This enables batch processing, personalization systems, and automated design production.
This guide covers how to load templates, populate variables, update placeholder content, and export to various formats including batch generation workflows.
Loading Templates#
Load templates from various sources before populating and exporting. Use engine.scene.loadFromURL() for remote templates, engine.scene.loadFromString() for serialized data, or engine.scene.loadFromArchiveURL() for templates with embedded assets.
// Load a template from URL - this template has visible {{variable}} placeholdersawait engine.scene.loadFromURL( 'https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_2.scene');console.log( 'Template loaded - variable placeholders like {{first_name}}, {{city}} are now visible on the canvas');Populating Variables#
CE.SDK’s variable system allows you to set values that replace {{variableName}} placeholders throughout the template. Before setting variables, you can discover what variables are available using engine.variable.findAll().
Discover Available Variables#
Find all variables defined in a template to understand what data can be populated.
// Discover available variables in the templateconst allVariables = engine.variable.findAll();console.log('Available variables:', allVariables);Set Variable Values#
Use engine.variable.setString() to assign values that automatically replace placeholders in text blocks.
// Set variable values to replace {{variableName}} placeholdersengine.variable.setString('first_name', 'Alice');engine.variable.setString('last_name', 'Smith');engine.variable.setString('city', 'Paris');engine.variable.setString('address', '10 Rue de Rivoli');console.log('Variables populated - placeholders replaced with values');Updating Placeholder Content#
Beyond variables, templates often contain placeholder blocks for images and other content. Find these blocks using engine.block.findByName() or engine.block.findAllPlaceholders().
// Find all placeholder blocks in the templateconst placeholders = engine.block.findAllPlaceholders();console.log('Found placeholders:', placeholders.length);
// Find specific blocks by nameconst namedBlocks = engine.block.findByName('Image');if (namedBlocks.length > 0) { console.log('Found image block by name:', namedBlocks[0]);}Update Image Placeholders#
Locate image blocks and modify their fill URI using engine.block.getFill() and engine.block.setString() on the 'fill/image/imageFileURI' property.
// Update image placeholder contentconst imageBlocks = engine.block.findByName('Image');if (imageBlocks.length > 0) { const imageBlock = imageBlocks[0]; const fill = engine.block.getFill(imageBlock); engine.block.setString( fill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/sample_4.jpg' ); console.log('Image placeholder updated');}Exporting to Images#
Generate image outputs using engine.block.export() with options for format, resolution, and quality. Find the page to export with engine.block.findByType('page').
// Export the populated template to PNGconst pages = engine.block.findByType('page');if (pages.length > 0) { const page = pages[0]; const blob = await engine.block.export(page, { mimeType: 'image/png', targetWidth: 1920, targetHeight: 1080 }); console.log('Exported to PNG:', blob.size, 'bytes');
// Create downloadable file const url = URL.createObjectURL(blob); console.log('Download URL created:', url); // In a real application, you would trigger a download: // const link = document.createElement('a'); // link.href = url; // link.download = 'greeting-card.png'; // link.click(); // URL.revokeObjectURL(url);}You can configure export options including targetWidth and targetHeight for output resolution, pngCompressionLevel for PNG files (0-9), and jpegQuality for JPEG files (0-1).
Exporting to PDF#
Use mimeType: 'application/pdf' to generate PDF documents from design scenes. For multi-page documents, export the scene block rather than individual pages.
// Export to PDF formatconst scene = engine.scene.get();if (scene !== null) { const pdfBlob = await engine.block.export(scene, { mimeType: 'application/pdf' }); console.log('Exported to PDF:', pdfBlob.size, 'bytes');}Batch Generation Workflows#
Process multiple data records through a single template. Save the template once with engine.scene.saveToString(), then loop through records—reloading the template with engine.scene.loadFromString(), populating variables, and exporting for each iteration.
// Demonstrate batch generation workflow// Save template for reuseconst templateString = await engine.scene.saveToString();console.log('Template saved for batch processing');
// Process multiple data recordsconst dataRecords = [ { firstName: 'Alice', lastName: 'Smith', city: 'Paris', address: '10 Rue de Rivoli' }, { firstName: 'Bob', lastName: 'Johnson', city: 'London', address: '221B Baker Street' }, { firstName: 'Carol', lastName: 'Williams', city: 'Tokyo', address: '1-1 Shibuya' }];
for (const record of dataRecords) { // Reload template for each record await engine.scene.loadFromString(templateString);
// Populate with record data engine.variable.setString('first_name', record.firstName); engine.variable.setString('last_name', record.lastName); engine.variable.setString('city', record.city); engine.variable.setString('address', record.address);
console.log( `Processed record for: ${record.firstName} ${record.lastName}` ); // In a real workflow, you would export here: // const blob = await engine.block.export(page, { mimeType: 'image/png' });}
console.log(`Batch processed ${dataRecords.length} records`);Troubleshooting#
Template Loading Fails#
Verify URL accessibility and scene format version compatibility. Wrap loading calls in try-catch blocks to handle network or parsing errors. Ensure the URL returns valid scene data and not HTML or other content.
Variables Not Updating#
Ensure variable names in text blocks (within {{}}) exactly match keys passed to engine.variable.setString(). Variable names are case-sensitive. Use engine.variable.findAll() to discover available variable names.
Export Returns Empty or Corrupted Output#
Confirm all required assets are accessible before exporting. Check that blocks are attached to the page hierarchy—orphaned blocks won’t appear in exports. Verify the page has visible content by checking block visibility states.
Image Placeholders Not Found#
Verify the exact name string matches what’s set in the template. Names are case-sensitive. Use engine.block.findAllPlaceholders() to discover all placeholder blocks in the scene.
API Reference#
| Method | Description |
|---|---|
scene.loadFromURL(url) | Load template from remote URL |
scene.loadFromString(data) | Load template from serialized string |
scene.loadFromArchiveURL(url) | Load archived template with embedded assets |
scene.saveToString() | Serialize scene for batch processing |
variable.setString(name, value) | Set text variable value |
variable.getString(name) | Retrieve current variable value |
variable.findAll() | List all variable names in scene |
block.findByName(name) | Find blocks by name identifier |
block.findByType(type) | Find blocks by type (e.g., ‘page’) |
block.findAllPlaceholders() | Discover all placeholder blocks |
block.getFill(block) | Get fill block from graphic block |
block.setString(block, property, value) | Set string properties like image URIs |
block.export(block, options) | Export block to image or PDF blob |