How do I generate a template?
Every component inherits generateTemplate(): string from BaseComponent. render() calls it and assigns the (sanitized) result to the component's innerHTML.
You can override it when a template needs more than a single expression.
When to use it
- The markup branches or is assembled conditionally
- The template needs instance state rather than only the
configargument atemplateFnreceives.
In a Component
Don't pass a templateFn to super().
- Override
generateTemplate()and read fromthis.configinstead:
// avatar.component.ts
import { Component, ComponentProps } from '../../../core/index.js';
interface AvatarConfig {
alt: string;
src?: string;
initials?: string;
shape?: 'circle' | 'square';
}
export class AvatarComponent extends Component<HTMLDivElement, AvatarConfig> {
constructor(mountTarget: HTMLElement, config: AvatarConfig, props?: ComponentProps) {
super({ mountTarget, config, normalizeKeys: ['src', 'initials', 'shape'], props });
}
protected override onBeforeRender(): void {
super.onBeforeRender();
this.element.classList.add('app-avatar', `avatar--${this.config.shape || 'circle'}`);
}
protected override generateTemplate(): string {
const { src, alt, initials } = this.config;
if (src) {
return `<img class="avatar__img" src="${src}" alt="${alt}" loading="lazy">`;
}
return `<span class="avatar__initials" aria-hidden="true">${initials}</span>`;
}
}
- Attributes that depend on optional flags can be built as a list:
protected override generateTemplate(): string {
const { id, name, checked, disabled } = this.config;
const attrs = [
'type="checkbox"',
id ? `id="${id}"` : '',
name ? `name="${name}"` : '',
checked ? 'checked' : '',
disabled ? 'disabled' : '',
].filter(Boolean).join(' ');
return `<input ${attrs}>`;
}
Notes
- The string you return still goes through the full pipeline: sanitized according to
trustLevel, then children are mounted,data-i18n/data-pipeare hydrated, emptydata-optionalelements are removed anddata-eventlisteners are bound. - Interpolated user data isn't escaped for you. Use
SecurityHelper.escapeHtml(), see How do I control HTML sanitization?. - Work on the rendered children (e.g.
querySelector) belongs inonAfterRender(). In aComponent, callsuper.onBeforeRender()/super.onAfterRender().