Async Rendering¶
miki-template supports async rendering for templates that use async filters, async custom tags, or async library components. Use asyncRender() instead of render() to await these operations.
Table of Contents¶
When to Use Async Rendering¶
Use asyncRender() when your templates contain any of the following:
-
Async filters — filters that return Promises
-
Async custom tags — custom tags whose
render()returns a Promise -
Async library components — i18n translations loaded dynamically
-
Async helpers — helpers that perform I/O
If you use async features with render() or compiled.render(), the engine throws:
Async node encountered during sync render. Use asyncRender() instead.
asyncRender()¶
With Views and Partials¶
compiled.asyncRender()¶
When you pre-compile a template, the returned object has asyncRender() and asyncRenderWith() methods:
Async Filters¶
Filters that return Promises are automatically awaited when using asyncRender():
Usage:
Real-world CMS content fetch:
const { registerFilter, asyncRender } = require('miki-template');
registerFilter('cms_content', async (id) => {
const res = await fetch(`https://cms.example.com/api/content/${id}`);
const data = await res.json();
return data.html;
});
const html = await asyncRender(
'{% autoescape off %}{{ page_id|cms_content }}{% endautoescape %}',
{ page_id: 'about' }
);
import { registerFilter, asyncRender } from 'miki-template';
registerFilter('cms_content', async (id) => {
const res = await fetch(`https://cms.example.com/api/content/${id}`);
const data = await res.json();
return data.html;
});
const html = await asyncRender(
'{% autoescape off %}{{ page_id|cms_content }}{% endautoescape %}',
{ page_id: 'about' }
);
Async Custom Tags¶
Custom tags whose render() returns a Promise work with asyncRender():
const { registerTag, asyncRender } = require('miki-template');
registerTag('api_data', (tagContent, parser) => {
const endpoint = tagContent.trim();
return {
async render(context) {
const res = await fetch(context.get(endpoint));
const data = await res.json();
return JSON.stringify(data, null, 2);
}
};
});
const html = await asyncRender(
'{% api_data api_url %}',
{ api_url: 'https://api.example.com/users' }
);
import { registerTag, asyncRender } from 'miki-template';
registerTag('api_data', (tagContent, parser) => {
const endpoint = tagContent.trim();
return {
async render(context) {
const res = await fetch(context.get(endpoint));
const data = await res.json();
return JSON.stringify(data, null, 2);
}
};
});
const html = await asyncRender(
'{% api_data api_url %}',
{ api_url: 'https://api.example.com/users' }
);
Express Async Engine¶
For Express apps with async templates, use __expressAsync or express({ async: true }):
Express 5+ Native Promise Support¶
If you're using Express 5 (which supports Promise-based view engines), use __expressAsync directly:
asyncRenderWith()¶
Override compile-time options at render time: