HTmp is a versatile HTML templating library designed for developers who need dynamic and customizable server-side HTML generation. It processes HTML templates with advanced features like conditional rendering, loops, dynamic components, and more, providing an expressive way to build complex templates.
- Components: Define reusable HTML components with support for scoped properties.
- Dynamic Attribute Values: Evaluate and include attributes dynamically as JavaScript expressions.
- Conditional Rendering: Render elements conditionally using
<if>
,<elseif>
, and<else>
tags. - Switch/Case Rendering: Define conditional rendering blocks with
<switch>
and<case>
tags. - Loops: Iterate over arrays directly in your templates with
<for>
tags. - Dynamic Tags: Dynamically set HTML tag names using template logic.
- Slot and Yield System: Support for content slots and dynamic content replacement.
- Stacks: Define stackable content and include it anywhere in your templates.
- Prettify Output: Automatically format the output HTML using Prettier.
Install HTmp via npm:
npm install @zachsents/htmp
import { HTmpCompiler } from "htmp";
const compiler = new HTmpCompiler({
components: {
"header-component": "<header><h1>{{title}}</h1></header>",
},
pretty: true,
});
const template = `
<if condition="user.isLoggedIn">
<p>Welcome, {{user.name}}!</p>
<elseif condition="user.isGuest" />
<p>Welcome, Guest!</p>
<else>
<p>Please log in.</p>
</if>`;
const html = await compiler.compile(template, { user: { isLoggedIn: true, name: "John" } });
console.log(html);
The HTmpCompiler
accepts an options object:
components
: Object mapping component names to their HTML strings.componentsRoot
: Path to load components from disk.dynamicTag
: Tag used for dynamic tags (default:<dynamic>
).pretty
: Format the output HTML (default:false
).evalContext
: Default context for evaluating template expressions.debug
: Enable debugging output (default:false
).attributeMergeStrategies
: Custom merging strategies for attributes.
Dynamic attribute evaluation is a powerful feature in HTmp. Attributes prefixed with eval:
are interpreted as JavaScript expressions and evaluated in the current scope:
<div eval:id="'dynamic-' + user.id"></div>
This mechanic is also at play in dynamic component names, as shown below:
<component eval:name="dynamicComponentName" title="Welcome!" />
Components allow for reusable template snippets. There are two ways to use components:
Use the x-
prefix to define components inline:
<x-header-component title="Welcome!" />
Alternatively, use the <component>
tag:
<component name="header-component" title="Welcome!" />
You can use eval:name
to dynamically determine the component name:
<component eval:name="dynamicComponentName" title="Welcome!" />
<if condition="user.isLoggedIn">
<p>Welcome, {{user.name}}!</p>
</if>
<elseif condition="user.isGuest">
<p>Welcome, Guest!</p>
</elseif>
<else>
<p>Please log in.</p>
</else>
<switch value="user.role">
<case case="'admin'">
<p>Welcome, Admin!</p>
</case>
<case case="'user'">
<p>Welcome, User!</p>
</case>
<case default>
<p>Welcome, Guest!</p>
</case>
</switch>
<for item="item" in="items">
<li>%% item %%</li>
</for>
Define slots in components to allow content insertion:
<template>
<div>
<div class="header">
<slot name="header">Default Header</slot>
</div>
<div class="content">
<slot>Default Content</slot>
</div>
</div>
</template>
Use slots in a parent template:
<x-layout>
<fill slot="header">
<h1>Title</h1>
</fill>
<fill>
<p>Main Content</p>
</fill>
</x-layout>
<dynamic tag="user.tag">
<p>Dynamic Content</p>
</dynamic>
<push stack="scripts">
<script src="/app.js"></script>
</push>
<stack name="scripts" />
To preload components:
await compiler.preloadComponents();
HTmpCompiler.compile(html: string, additionalEvalContext?: Record<string, unknown>): Promise<string>
Compiles the given HTML template with an optional evaluation context.
Preloads components from the componentsRoot
directory.
The library supports detailed configuration through the HTmpCompileOptions
interface. Refer to the options
documentation for fine-grained control over behavior.
HTmp throws meaningful errors when templates are improperly defined. Examples include:
- Missing required attributes for tags like
<if>
or<for>
. - Invalid component definitions.
- Evaluation errors in template expressions.
Enable debugging to view intermediate HTML states:
const compiler = new HTmpCompiler({ debug: true });
This project is licensed under the MIT License. See the LICENSE file for details.