Covers Zhin component rendering, defineComponent usage, and message template composition. Use when creating reusable message UI components.
Install
npx skillscat add zhinjs/ai-skills/zhin-component-rendering Install via the SkillsCat registry.
This skill documents how to build reusable message UI components in the Zhin framework using defineComponent, template tags, and props with inline expressions. It addresses the need to compose structured, composable messages rather than sending plain text. Developers should use it when creating custom, reusable rendering components for bot messages in Zhin.
Zhin Component Rendering Skill
Use this skill when developers need to create reusable message components with Zhin's component system.
Define and Register a Component
import { defineComponent, usePlugin } from '@zhin.js/core'
const plugin = usePlugin()
const StatusCard = defineComponent((props: { title: string, value: string }, context) => {
return `<text>${props.title}: ${props.value}</text>`
}, 'status-card')
plugin.addComponent(StatusCard)Template Usage
Components render within message templates:
await message.$reply('<status-card title="CPU" value="40%"/>')You can nest components:
await message.$reply('<Fragment><status-card title="Memory" value="512MB"/></Fragment>')Props & Expressions
Props support inline expressions with {} and template interpolation via ${} when rendering:
const Card = defineComponent((props: { title: string, count: number }) => {
return `<text>${props.title}: ${props.count}</text>`
}, 'card')
await message.$reply('<card title="Jobs" count="{1 + 2}"/>')Rendering Lifecycle
The component service attaches a before.sendMessage listener to render templates before messages send.
If you need to pre-render a template manually, use renderComponents:
import { renderComponents } from '@zhin.js/core'
const options = await renderComponents(componentService.byName, {
context: 'process',
bot: 'dev',
type: 'private',
id: '123',
content: '<status-card title="CPU" value="40%"/>'
})Built-in Components
Zhin includes:
Fragmentfor grouping/children renderingfetchfor loading remote content (use carefully and validate URLs)
Best Practices
- Keep components small and reusable.
- Validate and sanitize user input before passing it into templates.
- Avoid untrusted URLs with the
fetchcomponent.