Creating Dynamic Content
Dynamic content in Canvelete (opens in a new tab) transforms how you think about customer communication. Instead of creating generic, one-size-fits-all materials, you create smart templates that adapt to each customer's unique situation.
Turn One Design Into Thousands of Personal Connections
Dynamic content transforms how you think about customer communication. Instead of creating generic, one-size-fits-all materials, you create smart templates that adapt to each customer's unique situation. Your design becomes a living, breathing system that responds to your business data.
What This Means for Your Business
When you master dynamic content, you unlock capabilities that seemed impossible before. Your marketing team can launch personalized campaigns at scale. Your sales team can generate custom proposals in minutes. Your customer success team can create tailored onboarding materials for every new client.
The magic happens because your designs become data-aware. They know who your customer is, what they've purchased, when they joined, and what matters to them. This isn't just about efficiency – it's about creating genuine connections with every person who interacts with your brand.
Dynamic Element Types
Text Elements
Text elements are the most common dynamic components. They can display:
- Simple Variables: Direct data substitution
- Formatted Text: Numbers, dates, currencies with specific formatting
- Conditional Text: Different text based on data conditions
- Calculated Values: Mathematical operations on data
1
{
2
400">class="text-green-400">"productName": 400">class="text-green-400">"{{product.name}}",
3
400">class="text-green-400">"price": 400">class="text-green-400">"{{product.price | currency}}",
4
400">class="text-green-400">"discount": 400">class="text-green-400">"{{product.originalPrice - product.price | currency}}",
5
400">class="text-green-400">"availability": 400">class="text-green-400">"{{product.stock > 0 ? 'In Stock' : 'Out of Stock'}}"
6
}
Image Elements
Dynamic images can change based on data inputs:
- Product Images: Display different product photos
- Profile Pictures: User avatars or team member photos
- Background Images: Contextual backgrounds based on content
- Logo Variations: Different brand logos for various contexts
1
{
2
400">class="text-green-400">"profileImage": 400">class="text-green-400">"{{user.avatar || 'https:400">class="text-gray-500">//example.com/default-avatar.jpg'}}",
3
400">class="text-green-400">"backgroundImage": 400">class="text-green-400">"{{user.coverPhoto}}",
4
400">class="text-green-400">"companyLogo": 400">class="text-green-400">"{{user.company.logo}}"
5
}
Notice the || operator in the profile image example. Always provide fallback values for dynamic images in case the user data is missing. This ensures your designs always look professional, even with incomplete data.
Shape and Color Elements
Visual elements that adapt to data:
- Progress Bars: Visual representation of completion or metrics
- Color Coding: Different colors based on status or category
- Size Variations: Element sizes based on numerical data
- Visibility: Show/hide elements based on conditions
// Example: Dynamic status indicator
{
"statusColor": "{{status === 'active' ? '#22c55e' : '#ef4444'}}",
"progressWidth": "{{(completed / total) * 100}}%",
"priorityIcon": "{{priority === 'high' ? 'warning' : 'info'}}"
}Creating Your First Dynamic Template
Step 1: Design the Base Template
Start by creating a static version of your design with placeholder content:
- Open the Canvelete Design Editor
- Create your layout with static text and images
- Identify which elements should be dynamic
- Note the positioning and styling of each element
Step 2: Add Dynamic Placeholders
Replace static content with dynamic placeholders:
// Before (static)
"Welcome John Doe"
// After (dynamic)
"Welcome {{user.firstName}} {{user.lastName}}"Step 3: Define Data Structure
Create a clear data structure that your template expects:
{
"user": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"avatar": "https://example.com/avatar.jpg"
},
"company": {
"name": "Acme Corp",
"logo": "https://example.com/logo.png"
},
"metrics": {
"sales": 15000,
"growth": 12.5,
"target": 20000
}
}Step 4: Test with Sample Data
Always test your dynamic template with various data scenarios:
- Complete Data: All fields populated
- Missing Data: Some fields empty or null
- Edge Cases: Very long text, special characters
- Boundary Values: Maximum/minimum numbers
Advanced Dynamic Content Patterns
Nested Data Structures
Handle complex data relationships:
// Accessing nested properties
"{{order.customer.address.city}}"
// Iterating through arrays
"{{#each products}}
Product: {{name}} - Price: {{price}}
{{/each}}"
// Conditional nested access
"{{order.customer.company?.name || 'Individual Customer'}}"Data Transformations
Apply transformations to your data:
// Text transformations
"{{user.name | uppercase}}"
"{{description | truncate:50}}"
"{{title | titlecase}}"
// Number formatting
"{{price | currency:'USD'}}"
"{{percentage | percent:2}}"
"{{fileSize | bytes}}"
// Date formatting
"{{createdAt | date:'YYYY-MM-DD'}}"
"{{updatedAt | timeAgo}}"Complex Calculations
Perform calculations within templates:
// Mathematical operations
"{{(revenue - costs) / revenue * 100 | round:2}}%"
// Conditional calculations
"{{salesTarget > actualSales ? salesTarget - actualSales : 0}}"
// Array operations
"{{products | sum:'price'}}"
"{{reviews | average:'rating' | round:1}}"Best Practices
Data Validation
Always validate your data before rendering:
// Check for required fields
"{{user.name || 'Anonymous User'}}"
// Validate data types
"{{typeof price === 'number' ? price : 0}}"
// Handle arrays safely
"{{products && products.length > 0 ? products[0].name : 'No products'}}"Performance Optimization
- Keep data structures flat when possible
- Use efficient filters and transformations
- Cache frequently used calculations
- Minimize nested loops in templates
Error Handling
Implement graceful error handling:
// Safe property access
"{{user?.profile?.bio || 'No bio available'}}"
// Try-catch for complex operations
"{{try (calculateDiscount(price, discount)) catch 'Price unavailable'}}"Common Use Cases
E-commerce Product Cards
{
"product": {
"name": "Wireless Headphones",
"price": 199.99,
"originalPrice": 249.99,
"rating": 4.5,
"reviews": 1247,
"image": "https://example.com/headphones.jpg",
"inStock": true,
"category": "Electronics"
}
}Social Media Posts
{
"post": {
"author": "Jane Smith",
"avatar": "https://example.com/jane.jpg",
"content": "Just launched our new product!",
"timestamp": "2024-01-15T10:30:00Z",
"likes": 42,
"comments": 8,
"image": "https://example.com/product-launch.jpg"
}
}Business Reports
{
"report": {
"period": "Q4 2023",
"revenue": 1250000,
"growth": 15.3,
"customers": 5420,
"metrics": [
{"name": "Sales", "value": 1250000, "change": 12.5},
{"name": "Customers", "value": 5420, "change": 8.2}
]
}
}Next Steps
- Learn about Data Binding for connecting your data sources
- Explore Template Variables for advanced variable usage
- Master Conditional Rendering for complex logic