vitemple / docs
THE BASICS / COMPOSITION

HTML, with
a little reuse.

A slot is a build-time instruction. The compiler reads its source and inserts the fragment into the parent page.

01

Import HTML

Paths are relative to the importing file. Components can import other components; circular imports produce an error.

src/index.html
<slot src="./components/card.html" title="A small beginning" />
src/components/card.html
<article class="card">
  <h2>{title}</h2>
  <p>Plain HTML. Reused anywhere.</p>
</article>
02

Pass attributes

Named attributes, including src and type, are available as {name} or { name }. Unknown placeholders remain unchanged. Substitutions are plain text: use trusted author-provided values, not unescaped user input.

Placeholders work in component markup and inline scripts. Style blocks are excluded so instances can share the same CSS.
03

Add styles and scripts

Style blocks are collected into the authored head and deduplicated by CSS content. Styles are global: use component classes to avoid selector collisions.

Component assets
<slot src="./card.css" type="css" />
<slot src="./card.ts" type="script" />

TypeScript is transpiled. Slot scripts are included in the combined module, while relative imported files are copied into dist and TypeScript imports become JavaScript. Ordinary inline component scripts get isolated wrappers.

04

Keep a reusable template

For dynamic content that depends on data available while the page is running, Vitemple provides <slot type="template"> . It imports a component as a native HTML template: a reusable starting point for creating DOM elements dynamically. Use it for lists, search results, or cards added after a user action or an API response.

The template stays hidden until your script clones its content. You can render as many independent copies as you need, populate each copy with runtime data, and insert it into the page. Attributes such as id are forwarded to the template; src and type control the import.

Parent page
<slot src="./item.html" type="template" id="item" />
<section id="items"></section>
item.html
<article class="item">
  <h3 data-title></h3>
</article>
scripts.ts
const template = document.querySelector<HTMLTemplateElement>('#item');
const container = document.querySelector('#items');
const items = [{ title: 'First card' }, { title: 'Second card' }];

for (const item of items) {
    const fragment = template.content.cloneNode(true) as DocumentFragment;
    const heading = fragment.querySelector('[data-title]');
    if (heading) heading.textContent = item.title;
    container.append(fragment);
}
One template, two independent cards.

The loop renders “First card” and “Second card” from the same component. Here the data is a small array; it could also come from an API or user input. The script fills each clone using native DOM APIs, so there is no need to rebuild the page for every new item.

Slot attributes on the template import are still resolved at build time. Runtime values are assigned by your script, as with textContent above

Template scripts are extracted and scheduled once at DOMContentLoaded. They do not execute separately for each clone; initialize later-created clones explicitly.

Next: Shared store →