🏎️ JavaScript Hypertext Preprocessor.
Rendu is a lightweight toolkit for mixing HTML and JavaScript with a focus on simplicity, standards and progressive rendering.
[!WARNING]
This is an experimental PoC.
[!NOTE]
See playground (online playground) for demos and syntax section for usage.
Using the rendu CLI, you can start a local web server to serve static files and render .html files as templates (powered by srvx).
npx rendu
compileTemplate(template, opts)Compile a template string into a render function.
undefinedExample:undefined
import { compileTemplate } from "rendu";
const template = `
<h1><?= title ?></h1>
<ul>
<? for (const item of items) { ?>
<li><?= item ?></li>
<? } ?>
</ul>
`;
const render = compileTemplate(template, { stream: false });
const html = await render({ title: "My List", items: ["Item 1", "Item 2", "Item 3"] });
console.log(html);
// Output:
// <h1>My List</h1>
// <ul>
// <li>Item 1</li>
// <li>Item 2</li>
// <li>Item 3</li>
// </ul>
compileTemplateToString(template, opts, asyncWrapper?)Compile a template string into a render function code string.
undefinedNote: This function is for advanced use cases where you need the generated code as a string.
createRenderContext(options)hasTemplateSyntax(template)Check if a template string contains template syntax.
renderToResponse(htmlTemplate, opts)Renders an HTML template to a Response object.
undefinedExample:undefined
import { compileTemplate, renderToResponse } from "rendu";
const render = compileTemplate(template, { stream: true });
const response = await renderToResponse(render, { request });
Rendu uses PHP-style tags to embed JavaScript within HTML templates:
Use <script server> to execute JavaScript on the server where it appears:
<script server>
globalThis.visitedPagesCount ??= 0;
globalThis.visitedPagesCount++;
</script>
Use <?= expression ?> to output values:
<h1><?= title ?></h1>
<div>Page visited: <?= visitedPagesCount ?></div>
Use <? ... ?> for JavaScript control flow:
<? if (items.length === 0) { ?>
<p>No items found.</p>
<? } ?> <? for (const item of items) { ?>
<li><?= item.name ?></li>
<? } ?>
Use echo() function for streaming content. Accepts: strings, functions, Promises, Response objects, or ReadableStreams:
undefinedExamples:undefined
<!-- Simple string output -->
<script server>
echo("Welcome to our site!");
</script>
<!-- Async content from API (non blocking)-->
<script server>
echo("Hello");
echo(async () => fetch("https://api.example.com/data"));
echo(() => "World");
</script>
Access request context and global state:
$REQUEST: The incoming Request object$METHOD: HTTP method (GET, POST, etc.)$URL: Request URL object$HEADERS: Request headers$COOKIES: Read-only object containing request cookies$RESPONSE: Response configuration objectUse setCookie() function to set cookies in the response:
<script server>
setCookie("user", "RenduUser");
setCookie("session", "abc123", { maxAge: 3600, httpOnly: true });
</script>
Access cookies from the request using $COOKIES:
<div>Welcome, <?= $COOKIES["user"] || "Guest" ?>!</div>
Use redirect() function to redirect the user:
<script server>
if (!$COOKIES["auth"]) {
redirect("/login");
}
</script>
The htmlspecialchars() function is available for escaping HTML content:
<div><?= htmlspecialchars(userInput) ?></div>
Published under the MIT license.
We use cookies
We use cookies to analyze traffic and improve your experience. You can accept or reject analytics cookies.