Frontend vs Backend Events
Frontend Events: Immediate UI updates, client-side tracking, user feedback
Backend Webhooks: Data persistence, server-side processing, integrations with other systems
Use both for a complete integration experience.
Webhooks allow you to receive real-time notifications when users save or download templates in your embedded editor. This enables you to track user activity, sync data, and trigger workflows in your application.
When a user performs an action in the embedded editor, Templated sends a POST request to your webhook URL with details about the action.
User performs action (create, save or download) in the embedded editor
Templated processes the action and captures relevant data
HTTP POST request sent to your configured webhook URL
Your server receives and processes the webhook data
Your application responds with appropriate actions or data storage
Set up your webhook URL in the embed configuration:
Go to your Embed Setup page
Expand Advanced Settings
Enter your webhook URL in the Webhook URL field
Save your configuration
Webhooks are triggered for the following actions:
Triggered when a user creates a new template in the embedded editor.
{ "event": "create", "timestamp": "2024-03-20T10:30:00Z", "templateId": "tpl_456def", "templateName": "New Design"}
Triggered when a user saves a template in the embedded editor.
{ "event": "save", "timestamp": "2024-03-20T10:30:00Z", "templateId": "tpl_456def", "templateName": "Updated Design",}
Triggered when a user downloads a template from the embedded editor.
{ "event": "download", "timestamp": "2024-03-20T10:35:00Z", "templateId": "tpl_456def", "templateName": "Final Design",}
You can also listen for events directly in the frontend using the postMessage
API. This is useful for immediate UI updates or client-side tracking.
window.addEventListener('message', (event) => { // Verify origin for security if (event.origin !== 'https://app.templated.io') { return; }
const { action, templateId } = event.data;
switch (action) { case 'create': console.log('Template created:', templateId); // Update UI, show success message, etc. break;
case 'save': console.log('Template saved:', templateId); // Track analytics, update download count, etc. break;
case 'download': console.log('Template downloaded:', templateId); // Handle cleanup, redirect, etc. break; }});
Frontend vs Backend Events
Frontend Events: Immediate UI updates, client-side tracking, user feedback
Backend Webhooks: Data persistence, server-side processing, integrations with other systems
Use both for a complete integration experience.
const express = require('express');const app = express();
// Middleware to parse JSONapp.use(express.json());
app.post('/api/templated-webhook', (req, res) => { const { event, timestamp, template, render, user, metadata } = req.body;
console.log(`Received ${event} event from user ${user.embedUserId}`);
switch (event) { case 'create': handleCreateEvent(template, user, metadata); break;
case 'save': handleSaveEvent(template, user, metadata); break;
case 'download': handleDownloadEvent(render, template, user, metadata); break;
default: console.log('Unknown event type:', event); }
// Respond with 200 to acknowledge receipt res.status(200).json({ received: true });});
function handleCreateEvent(template, user, metadata) { // Your create logic here console.log(`Template ${template.id} created by ${user.embedUserId}`);}
function handleSaveEvent(template, user, metadata) { // Update user's project with new template // Log activity // Send notifications console.log(`Template ${template.id} saved by ${user.embedUserId}`);}
function handleDownloadEvent(render, template, user, metadata) { // Track download metrics // Update user quotas // Trigger follow-up workflows console.log(`Render ${render.id} downloaded by ${user.embedUserId}`);}
from flask import Flask, request, jsonifyimport jsonfrom datetime import datetime
app = Flask(__name__)
@app.route('/api/templated-webhook', methods=['POST'])def handle_webhook(): data = request.get_json()
event = data.get('event') timestamp = data.get('timestamp') template = data.get('template') render = data.get('render') user = data.get('user') metadata = data.get('metadata', {})
print(f"Received {event} event from user {user.get('embedUserId')}")
if event == 'create': handle_create_event(template, user, metadata) if event == 'save': handle_save_event(template, user, metadata) elif event == 'download': handle_download_event(render, template, user, metadata) else: print(f"Unknown event type: {event}")
return jsonify({'received': True}), 200
def handle_create_event(template, user, metadata): # Your create logic here print(f"Template {template['id']} created")
def handle_save_event(template, user, metadata): # Your save logic here print(f"Template {template['id']} saved")
def handle_download_event(render, template, user, metadata): # Your download logic here print(f"Render {render['id']} downloaded")
if __name__ == '__main__': app.run(debug=True)
<?php// webhook.php
// Get the JSON payload$input = file_get_contents('php://input');$data = json_decode($input, true);
if (!$data) { http_response_code(400); echo json_encode(['error' => 'Invalid JSON']); exit;}
$event = $data['event'] ?? '';$timestamp = $data['timestamp'] ?? '';$template = $data['template'] ?? [];$render = $data['render'] ?? [];$user = $data['user'] ?? [];$metadata = $data['metadata'] ?? [];
error_log("Received {$event} event from user " . ($user['embedUserId'] ?? 'unknown'));
switch ($event) { case 'create': handleCreateEvent($template, $user, $metadata); break;
case 'save': handleSaveEvent($template, $user, $metadata); break;
case 'download': handleDownloadEvent($render, $template, $user, $metadata); break;
default: error_log("Unknown event type: {$event}");}
// Respond with successhttp_response_code(200);echo json_encode(['received' => true]);
function handleCreateEvent($template, $user, $metadata) { // Your create logic here error_log("Template {$template['id']} created");}
function handleSaveEvent($template, $user, $metadata) { // Your save logic here error_log("Template {$template['id']} saved");}
function handleDownloadEvent($render, $template, $user, $metadata) { // Your download logic here error_log("Render {$render['id']} downloaded");}?>
Webhook not receiving data
→ Verify your webhook URL is publicly accessible
→ Check that your server responds with 200 status code
→ If you’re passing metadata, ensure you’re parsing JSON correctly
Missing metadata
→ Verify metadata is being passed in the embed URL in the correct format
→ Check that metadata is properly base64 encoded
Timeout errors
→ Ensure your webhook handler responds quickly (< 10 seconds)
→ Consider processing heavy operations asynchronously