HTML Templating
Sapling provides two main methods for rendering HTML content: html
and raw
. These are convenient wrappers around the html
and raw
methods from Hono.
The html Template Literal
The html
template literal allows you to write HTML with dynamic content interpolation:
import { html } from "@sapling/sapling";
function Greeting({ name }: { name: string }) {
return html`
<div class="greeting">
<h1>Hello, ${name}!</h1>
</div>
`;
}
Safety Features
The html
template automatically escapes interpolated values to prevent XSS attacks:
const userInput = '<script>alert("XSS")</script>';
html`<div>${userInput}</div>`; // Safely escaped
Nested Components
You can nest components and interpolate their results:
function Header() {
return html`<header>Site Header</header>`;
}
function Page() {
return html`
<div>
${Header()}
<main>Content</main>
</div>
`;
}
The raw Method
The raw
method is used when you need to insert pre-rendered HTML content without escaping:
import { html, raw } from "@sapling/sapling";
function Article({ content }: { content: string }) {
return html`
<article>
${raw(content)} <!-- Content is inserted as-is -->
</article>
`;
}
Use Cases for raw
- Rendering markdown content
- Inserting sanitized HTML from a CMS
- Including pre-rendered component output
import { renderMarkdown } from "@sapling/markdown";
async function MarkdownContent({ markdown }: { markdown: string }) {
const rendered = await renderMarkdown(markdown);
return html`
<div class="prose">
${raw(rendered)}
</div>
`;
}
Conditional Rendering
You can use standard JavaScript expressions within templates:
function ConditionalContent({ isLoggedIn }: { isLoggedIn: boolean }) {
return html`
<div>
${isLoggedIn
? html`<button>Logout</button>`
: html`<button>Login</button>`
}
</div>
`;
}
List Rendering
Render arrays of content using map:
function ItemList({ items }: { items: string[] }) {
return html`
<ul>
${items.map(item => html`
<li>${item}</li>
`)}
</ul>
`;
}
Best Practices
- Use html by Default: Always use the
html
template literal unless you specifically needraw
- Sanitize Raw Content: When using
raw
, ensure the content is from a trusted source or properly sanitized - Type Safety: Leverage TypeScript for component props
- Keep It Simple: Prefer small, focused components over complex templates
- Performance: Avoid unnecessary nesting of templates
Security Considerations
- The
html
template literal automatically escapes content to prevent XSS - Only use
raw
with trusted content - Always sanitize user-generated content before rendering
- Be cautious when rendering HTML from external sources