UI API — Template
apiClient.ui.template manages Nunjucks templates — reusable content definitions used to render UI components like cards and list items.
Templates are fetched with persistence and SWR (stale-while-revalidate) caching, so they load instantly from the cache while a fresh copy is fetched in the background.
Template Kinds
Templates have a kind field (from UI.CRUD.Kind) that determines how they are rendered:
| Kind | Description |
|---|---|
CARD | Card template for summary views |
LIST_ITEM | Row template for list views |
DETAIL | Full detail view template |
Methods
create
Create a new template.
const template = await apiClient.ui.template.create({
template: {
name: 'Job Card',
kind: 'CARD',
content: '<div>{{ name }}</div>',
},
})
console.log(template.uid)
get
Fetch a single template by UID.
const template = await apiClient.ui.template.get({ uid: 'abc123' })
getMany
Fetch multiple templates, with optional filters. Results are cached with SWR.
// All templates
const templates = await apiClient.ui.template.getMany({})
// By name
const named = await apiClient.ui.template.getMany({ name: 'Job Card' })
// Paginated
const page = await apiClient.ui.template.getMany({ limit: 20, page: 1 })
put
Update an existing template. Uses merge-and-put — only include the fields you want to change.
await apiClient.ui.template.put({
template: {
uid: 'abc123',
content: '<div class="card">{{ name }}</div>',
},
})
del
Delete a template by UID.
await apiClient.ui.template.del({ uid: 'abc123' })
getBestTemplate
Find the best-matching template by name (sorted by relevance). Returns null if none found.
const template = await apiClient.ui.template.getBestTemplate('Job Card')
if (template) {
console.log(template.content)
}
Template Type
A template object contains the following key fields:
| Field | Type | Description |
|---|---|---|
uid | string | Unique identifier |
name | string | Display name |
kind | UI.CRUD.Kind | Template kind enum |
content | string | Nunjucks template string (defaults to '') |
React Example
Security note:
dangerouslySetInnerHTMLrenders Nunjucks template output directly into the DOM. Ensure all values indatacome from trusted sources, or sanitize the rendered HTML with a library like DOMPurify before rendering. Template content itself should only come from trusted administrative sources, never from end-user input.
import { useApiClient } from '@skedulo/horizon-core'
import { useEffect, useState } from 'react'
import nunjucks from 'nunjucks'
const CardRenderer = ({ templateName, data }) => {
const apiClient = useApiClient()
const [html, setHtml] = useState('')
useEffect(() => {
apiClient?.ui.template.getBestTemplate(templateName).then((template) => {
if (template) {
setHtml(nunjucks.renderString(template.content, data))
}
})
}, [apiClient, templateName, data])
return <div dangerouslySetInnerHTML={{ __html: html }} />
}