Skip to content

Advanced Features

Take your embedded editor integration to the next level with these advanced features and customization options.

Custom Metadata

Pass custom data through the embed that will be sent to your webhooks, enabling you to track user context and trigger specific workflows.

Encoding Metadata

Metadata must be base64-encoded JSON and passed as a URL parameter:

Encoding Metadata
// Your custom metadata
const metadata = {
userId: "user-123",
projectId: "project-456",
clientId: "client-789",
workflowType: "marketing_campaign",
campaignId: "campaign-001"
};
// Encode as base64
const encodedMetadata = btoa(JSON.stringify(metadata));
// Create embed URL with metadata
const embedUrl = `https://app.templated.io/editor?embed=${configId}&metadata=${encodedMetadata}`;
// Update embed element
document.getElementById('editor-embed').src = embedUrl;

Dynamic Metadata Generation

Generate metadata dynamically based on user context:

Dynamic Metadata Example
function generateEmbedWithMetadata(user, project) {
const metadata = {
userId: user.id,
userName: user.name,
userEmail: user.email,
projectId: project.id,
projectName: project.name,
timestamp: new Date().toISOString(),
source: 'project_dashboard',
permissions: user.permissions,
subscription: user.subscription.plan
};
const encodedMetadata = btoa(JSON.stringify(metadata));
return `https://app.templated.io/editor?embed=${EMBED_CONFIG_ID}&metadata=${encodedMetadata}`;
}
// Usage
const embedUrl = generateEmbedWithMetadata(currentUser, currentProject);
document.getElementById('template-editor').src = embedUrl;

Pre-populate Template Data

Launch the editor with custom layer data to pre-populate templates with user-specific content.

Layer Data Structure

Layer Data Format
const layerData = {
"text-layer-name": {
text: "Custom text content",
color: "#FF0000",
font_size: "24px"
},
"image-layer-name": {
image_url: "https://example.com/user-photo.jpg"
},
"shape-layer-name": {
fill: "#0066CC",
stroke: "#003366"
}
};
// Encode layer data
const encodedLayers = btoa(JSON.stringify(layerData));

Template with Custom Data

Pre-populated Template Launch
<embed
src="https://app.templated.io/editor/TEMPLATE_ID?embed=CONFIG_ID&layers=ENCODED_LAYER_DATA"
width="100%"
height="100%"
/>

Dynamic Layer Population

User Profile Template
function createUserProfileTemplate(user) {
const layers = {
"user-name": {
text: user.fullName,
color: "#333333"
},
"user-title": {
text: user.jobTitle,
color: "#666666"
},
"profile-photo": {
image_url: user.profilePicture
},
"company-logo": {
image_url: user.company.logo
},
"background-color": {
fill: user.company.brandColor
}
};
const encodedLayers = btoa(JSON.stringify(layers));
return `https://app.templated.io/editor/${USER_PROFILE_TEMPLATE_ID}?embed=${EMBED_CONFIG_ID}&layers=${encodedLayers}`;
}

Render Editing

Allow users to edit existing renders, automatically creating template clones for safe editing.

Edit Existing Render

Render Editor Launch
<embed
src="https://app.templated.io/editor?embed=CONFIG_ID&render=RENDER_ID"
width="100%"
height="100%"
/>

Integration Example

Render Edit Integration
function editRender(renderId, userId) {
const metadata = {
userId: userId,
action: 'edit_render',
originalRenderId: renderId,
editMode: true
};
const encodedMetadata = btoa(JSON.stringify(metadata));
const embedUrl = `https://app.templated.io/editor?embed=${EMBED_CONFIG_ID}&render=${renderId}&metadata=${encodedMetadata}`;
// Open in modal or new window
openEditorModal(embedUrl);
}
// Usage in your UI
document.querySelectorAll('.edit-render-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const renderId = e.target.dataset.renderId;
editRender(renderId, currentUser.id);
});
});

Template Filtering by Folder

Limit template selection to specific folders:

Folder-filtered Templates
<!-- Show only templates from specific folder -->
<embed
src="https://app.templated.io/editor?embed=CONFIG_ID&folder=FOLDER_ID"
width="100%"
height="100%"
/>

Editor Event Monitoring

Monitor Editor Events
class EditorMonitor {
constructor(embedElement) {
this.embed = embedElement;
this.setupEventListeners();
}
setupEventListeners() {
// Monitor load events
this.embed.addEventListener('load', () => {
console.log('Editor loaded successfully');
this.trackEvent('editor_loaded');
});
// Monitor errors
this.embed.addEventListener('error', (e) => {
console.error('Editor failed to load:', e);
this.trackEvent('editor_error', { error: e.message });
this.showFallback();
});
}
trackEvent(eventName, data = {}) {
// Send to your analytics
analytics.track(eventName, {
...data,
timestamp: new Date().toISOString(),
embedConfigId: this.getConfigId()
});
}
showFallback() {
// Show fallback UI when editor fails to load
const fallback = document.createElement('div');
fallback.className = 'editor-fallback';
fallback.innerHTML = `
<div class="fallback-message">
<h3>Editor temporarily unavailable</h3>
<p>Please try refreshing the page or contact support.</p>
<button onclick="location.reload()">Refresh Page</button>
</div>
`;
this.embed.parentNode.replaceChild(fallback, this.embed);
}
getConfigId() {
const url = new URL(this.embed.src);
return url.searchParams.get('embed');
}
}
// Usage
const editorEmbed = document.getElementById('template-editor');
const monitor = new EditorMonitor(editorEmbed);

Best Practices for Advanced Features

Security:

  • Always validate metadata on your server
  • Sanitize user inputs before encoding
  • Use HTTPS for all embed URLs

Performance:

  • Implement lazy loading for multiple editors
  • Preload resources when appropriate
  • Monitor and optimize embed load times

User Experience:

  • Provide loading states and error fallbacks
  • Implement responsive design
  • Test across different devices and browsers