Transform your N8N workflows with powerful text templating - Generate dynamic content using Mustache, Handlebars, Nunjucks, or EJS template engines for AI prompts, email automation, reports, and more.
- Why Text Templater?
- Key Features
- Installation
- Quick Start Guide
- Templating Engines
- Use Cases
- Examples
- Configuration
- Best Practices
- Troubleshooting
- Contributing
- License
The N8N Text Templater is a must-have community node for anyone building automated workflows that require dynamic text generation. Whether you're creating AI prompts, personalizing emails, generating reports, or building API requests, this node provides professional-grade templating capabilities directly in your N8N workflows.
- AI & LLM Integration - Generate dynamic prompts for ChatGPT, Claude, GPT-4, and other AI models
- Email Marketing - Personalize bulk emails with customer data and conditional content
- Report Generation - Create formatted reports with charts, tables, and dynamic data
- API Development - Build dynamic JSON/XML payloads for REST APIs
- Documentation - Auto-generate technical docs, release notes, and changelogs
- Content Creation - Produce blog posts, social media content, and marketing copy
- Workflow Automation - Transform data between services with custom formatting
Choose from 4 industry-standard templating engines, each optimized for different use cases:
| Engine | Best For | Complexity | Performance |
|---|---|---|---|
| Mustache | Simple substitution | Beginner | ⚡ Fastest |
| Handlebars | Logic & loops | Intermediate | ⚡ Fast |
| Nunjucks | Filters & inheritance | Advanced | 🔥 Medium |
| EJS | JavaScript power | Expert | 🔥 Medium |
- Works immediately after installation
- Sensible defaults for all parameters
- No external dependencies or API keys required
- Runs entirely within your N8N instance
- Built-in XSS protection with autoescape
- Sandboxed template execution
- No
eval()or arbitrary code execution (except EJS) - Secure by default for all engines
- Fast template compilation and rendering
- Minimal memory footprint
- Batch processing support for multiple items
- Efficient caching for repeated templates
Every execution returns:
- Rendered text content
- Character and line counts
- Engine used for rendering
- Timestamp of generation
- Error details (if any)
- Full support for N8N expressions (
={{$json.field}}) - Works with all N8N data types
- Seamless integration with other nodes
- Visual workflow builder compatible
The easiest way to install the Text Templater node:
- Open your N8N instance
- Navigate to Settings → Community Nodes
- Click "Install a community node"
- Enter:
n8n-nodes-text-templater - Click Install and wait for completion
- Refresh your browser
For self-hosted N8N installations:
# Navigate to your N8N custom nodes directory
cd ~/.n8n/nodes
# Install the package
npm install n8n-nodes-text-templater
# Restart N8N
n8n restartAdd to your docker-compose.yml or environment variables:
services:
n8n:
image: n8nio/n8n
environment:
- N8N_COMMUNITY_PACKAGES=n8n-nodes-text-templater
ports:
- "5678:5678"Or use environment variable:
docker run -it --rm \
-e N8N_COMMUNITY_PACKAGES=n8n-nodes-text-templater \
-p 5678:5678 \
n8nio/n8nFor developers who want to modify the node:
# Clone the repository
git clone https://github.com/llmx-tech/n8n-nodes-text-templater.git
cd n8n-nodes-text-templater
# Install dependencies
npm install
# Build the node
npm run build
# Link for development
npm link
cd ~/.n8n/nodes
npm link n8n-nodes-text-templater
# Restart N8N
n8n restart- Click the "+" button in your N8N workflow
- Search for "Text Templater" or "template"
- Select the Text Templater node
Choose from Mustache, Handlebars, Nunjucks, or EJS based on your needs:
- Mustache: For simple variable replacement
- Handlebars: For conditional content and loops
- Nunjucks: For filters and template inheritance
- EJS: For full JavaScript expressions
Enter your template with placeholders for dynamic data:
Add your data as JSON:
{
"name": "John Doe",
"orderId": "12345"
}Click "Execute node" to see your rendered template:
Hello John Doe!
Your order #12345 has been confirmed.
Use Mustache when: You need simple variable substitution without complex logic.
Syntax: {{variable}}
Features:
- ✅ Variable substitution
- ✅ Sections (loops and conditionals)
- ✅ Comments
- ✅ Partials
- ❌ No complex logic
- ❌ No custom helpers
Example:
Variables:
{
"name": "Alice Smith",
"orderId": "ORD-12345",
"status": "shipped",
"premium": true,
"discount": 20
}Output:
Hello Alice Smith!
Your order #ORD-12345 has been shipped.
🌟 Thank you for being a premium member!
Enjoy your 20% discount.
Learn more: Mustache Documentation
Use Handlebars when: You need conditional logic, loops, and custom formatting.
Syntax: {{#if}}, {{#each}}, helpers
Features:
- ✅ All Mustache features
- ✅ If/else conditionals
- ✅ Each loops with @index
- ✅ Built-in helpers
- ✅ Custom helper support
- ✅ Block expressions
Example:
Variables:
{
"customer": {
"name": "Bob Johnson",
"isPremium": true,
"points": 1250,
"discountRate": 15
},
"items": [
{"name": "Laptop", "price": 999, "quantity": 1},
{"name": "Mouse", "price": 25, "quantity": 2}
],
"total": 1049,
"discountedTotal": 891.65
}Learn more: Handlebars Documentation
Use Nunjucks when: You need advanced formatting, filters, and template inheritance.
Syntax: {% if %}, {{ var | filter }}
Features:
- ✅ Jinja2-inspired syntax
- ✅ Powerful filters (upper, lower, replace, etc.)
- ✅ Template inheritance
- ✅ Macros and includes
- ✅ Async support
- ✅ Autoescape for security
Example:
# Welcome {{ name | title }}!
{% if memberSince %}
Member since: {{ memberSince | date("MMMM YYYY") }}
Status: {{ status | upper }}
{% endif %}
## Your Recent Activity
{% for activity in activities %}
- {{ activity.date | date("MMM DD") }}: {{ activity.description }}
{% if activity.important %}⭐ Important{% endif %}
{% endfor %}
{% if activities | length > 5 %}
Showing 5 of {{ activities | length }} activities.
{% endif %}
---
Email: {{ email | lower }}
Phone: {{ phone | default("Not provided") }}Variables:
{
"name": "charlie brown",
"memberSince": "2023-01-15",
"status": "gold",
"email": "Charlie.Brown@EXAMPLE.com",
"activities": [
{"date": "2025-11-01", "description": "Logged in", "important": false},
{"date": "2025-11-05", "description": "Made purchase", "important": true}
]
}Learn more: Nunjucks Documentation
Use EJS when: You need full JavaScript power for complex calculations.
Syntax: <%= expression %>, <% code %>
Features:
- ✅ Full JavaScript expressions
- ✅ Loops and conditionals with JS syntax
- ✅ Functions and calculations
- ✅ Array/object manipulation
⚠️ Powerful but less secure⚠️ Use only with trusted data
Example:
# Analytics Report - <%= new Date().toLocaleDateString() %>
## Performance Metrics
<%
const growth = ((metrics.current - metrics.previous) / metrics.previous * 100).toFixed(2);
const status = growth > 0 ? '📈 UP' : '📉 DOWN';
%>
- Total Revenue: $<%= metrics.current.toLocaleString() %>
- Previous Period: $<%= metrics.previous.toLocaleString() %>
- Growth: <%= status %> <%= Math.abs(growth) %>%
## Top Products
<% products.sort((a, b) => b.sales - a.sales).slice(0, 3).forEach((product, index) => { %>
<%= index + 1 %>. <%= product.name.toUpperCase() %>
Sales: $<%= product.sales.toLocaleString() %>
Units: <%= product.units %>
Avg Price: $<%= (product.sales / product.units).toFixed(2) %>
<% }); %>
## Summary
<% if (growth > 10) { %>
🎉 Excellent performance! Growth exceeded 10%.
<% } else if (growth > 0) { %>
✅ Positive growth. Keep it up!
<% } else { %>
⚠️ Negative growth. Review strategy.
<% } %>Variables:
{
"metrics": {
"current": 125000,
"previous": 98000
},
"products": [
{"name": "Widget Pro", "sales": 45000, "units": 150},
{"name": "Gadget Plus", "sales": 38000, "units": 200},
{"name": "Tool Master", "sales": 42000, "units": 100}
]
}Learn more: EJS Documentation
Generate dynamic prompts for ChatGPT, Claude, GPT-4, and other AI models:
Create personalized email campaigns:
Generate formatted business reports:
# {{ reportTitle }} - {{ reportDate | date("MMMM DD, YYYY") }}
## Executive Summary
Total Revenue: ${{ revenue | formatNumber }}
Total Orders: {{ orderCount }}
Average Order Value: ${{ (revenue / orderCount) | round(2) }}
{% if growthRate > 0 %}
📈 Revenue Growth: +{{ growthRate }}%
{% else %}
📉 Revenue Change: {{ growthRate }}%
{% endif %}
## Regional Performance
{% for region in regions %}
### {{ region.name }}
- Revenue: ${{ region.revenue | formatNumber }}
- Orders: {{ region.orders }}
- Top Product: {{ region.topProduct }}
{% endfor %}
## Insights
{% for insight in insights %}
- {{ insight }}
{% endfor %}Create dynamic API payloads:
{
"query": "{{searchQuery}}",
"filters": {
"category": "{{category}}",
"priceRange": {
"min": {{minPrice}},
"max": {{maxPrice}}
},
"inStock": {{inStock}},
"tags": [{{#each tags}}"{{this}}"{{#unless @last}},{{/unless}}{{/each}}]
},
"sort": {
"field": "{{sortField}}",
"order": "{{sortOrder}}"
},
"pagination": {
"page": {{page}},
"limit": {{pageSize}}
}
}Auto-generate technical documentation:
# API Documentation - {{apiName}} v{{version}}
## Endpoints
{{#each endpoints}}
### {{this.method}} {{this.path}}
**Description:** {{this.description}}
**Authentication:** {{#if this.requiresAuth}}Required{{else}}Not required{{/if}}
**Parameters:**
{{#each this.parameters}}
- `{{this.name}}` ({{this.type}}) - {{this.description}}
{{#if this.required}}**Required**{{else}}Optional{{/if}}
{{/each}}
**Example Request:**
\`\`\`{{this.exampleLanguage}}
{{this.exampleRequest}}
\`\`\`
**Response:**
\`\`\`json
{{this.exampleResponse}}
\`\`\`
---
{{/each}}Generate social media posts:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Templating Engine | Dropdown | Yes | Mustache | Choose the template engine |
| Template | String | Yes | - | The template string with placeholders |
| Variables | JSON | Yes | {} |
Data to populate the template |
The Template field automatically updates its placeholder based on the selected engine, showing you the appropriate syntax.
You can use N8N expressions in the Variables field:
// Pass all incoming data
={{$json}}
// Pass specific fields
={{"name": $json.customerName, "email": $json.email}}
// Combine static and dynamic data
={{"greeting": "Hello", "name": $json.name, "date": $now}}
// Use data from previous nodes
={{"userData": $node["Get User"].json, "orderId": $json.id}}The node returns:
{
"text": "The rendered template text",
"metadata": {
"engine": "mustache",
"charCount": 145,
"lineCount": 8,
"timestamp": "2025-11-08T10:30:00.000Z"
}
}- Simple substitution? → Use Mustache
- Need if/else? → Use Handlebars
- Need filters? → Use Nunjucks
- Need calculations? → Use EJS
- ✅ DO use Mustache/Handlebars for user-generated content
- ✅ DO enable autoescape in Nunjucks
⚠️ CAREFUL with EJS and untrusted data- ❌ DON'T put sensitive data in templates
- ❌ DON'T use EJS with user input without sanitization
- Keep templates under 10KB for best performance
- Cache frequently used templates upstream
- Use simpler engines (Mustache/Handlebars) when possible
- Process large batches in chunks
// Good: Clear, organized template
const template = `
Hello {{name}}!
{{#if premium}}
VIP Content
{{/if}}
`;
// Bad: Messy, hard to read
const template = "Hello {{name}}! {{#if premium}}VIP{{/if}}";Always handle potential errors in your workflow:
- Use an IF node to check for empty templates
- Add error handlers for invalid JSON in variables
- Test with edge cases (empty strings, null values)
- Monitor the metadata output for issues
- Refresh browser (Cmd+Shift+R or Ctrl+Shift+F5)
- Check installation:
cd ~/.n8n/nodes ls | grep text-templater
- Restart N8N:
n8n restart
- Check N8N logs for errors
- Check syntax matches selected engine
- Verify variable names match placeholders exactly
- Validate JSON in variables field
- Look at error messages in execution details
- Ensure JSON is valid (use a JSON validator)
- Check for typos in variable names
- Verify N8N expressions are correct:
={{$json.field}} - Test with static JSON first
- Reduce template size (break into smaller chunks)
- Use a simpler engine (Mustache instead of EJS)
- Process fewer items per execution
- Check for infinite loops in templates
| Error | Cause | Solution |
|---|---|---|
| "Invalid JSON" | Malformed variables | Validate JSON syntax |
| "Template syntax error" | Wrong syntax for engine | Check engine-specific docs |
| "Variable not found" | Missing data | Verify variable names |
| "Node not found" | Not installed | Reinstall the node |
We welcome contributions! Here's how you can help:
Found a bug? Create an issue with:
- N8N version
- Node version
- Template engine used
- Steps to reproduce
- Expected vs actual behavior
Have an idea? Open a feature request describing:
- The use case
- Proposed solution
- Alternative approaches considered
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests if applicable
- Run linting:
npm run lint:fix - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
# Clone your fork
git clone https://github.com/YOUR-USERNAME/n8n-nodes-text-templater.git
cd n8n-nodes-text-templater
# Install dependencies
npm install
# Build
npm run build
# Link for testing
npm link
cd ~/.n8n/nodes
npm link n8n-nodes-text-templater
# Start N8N in dev mode
n8n startThis project is licensed under the MIT License - see the LICENSE file for details.
- GitHub Repository: https://github.com/llmx-tech/n8n-nodes-text-templater
- npm Package: https://www.npmjs.com/package/n8n-nodes-text-templater
- Issues & Support: https://github.com/llmx-tech/n8n-nodes-text-templater/issues
- N8N Documentation: https://docs.n8n.io/integrations/community-nodes/
- LLMX Website: https://llmx.tech
If this node helps your workflow, please:
- ⭐ Star the repository on GitHub
- 📦 Rate the package on npm
- 🐦 Share with your network
- 💬 Contribute improvements
n8n n8n-node n8n-community-node workflow-automation template-engine mustache handlebars nunjucks ejs text-templating dynamic-content ai-prompts email-automation report-generation api-integration chatgpt gpt-4 claude workflow automation low-code no-code
Made with ❤️ by LLMX | Powered by N8N
