cursery.nixDocs

Pre-rendering

renderToString evaluates a Nix page and returns its HTML as a string. This guide renders one from Node.

Write the page#

A page is a function of its inputs that returns an html element.

src/page.nix
{ name }:
let
  inherit (import <web/dom>) html;
  inherit (import <web/static>) render;
  app = render (import ./app);
in
html.html { lang = "en"; } [
  (html.head [
    (html.title "Hello, ${name}")
    (html.style app.styles)
  ])
  (html.body [
    (html.div { id = "app"; } app.children)
  ])
]

render from <web/static> renders an app's initial state, returning its children and styles. Event handlers are omitted from the output.

Render it#

Load the Nix files, then render the page:

render.js
import { globSync, readFileSync } from "node:fs";
import { join } from "node:path";

import { load, renderToString, unload } from "cursery";

// Every Nix file under `src/`, by its path there.
const files = Object.fromEntries(
  globSync("**/*.nix", { cwd: "src" }).map((file) => [
    file,
    readFileSync(join("src", file), "utf8"),
  ]),
);

const path = load(files);
const html = renderToString(`${path}/page.nix`, { name: "Nix" });
unload(path);

console.log(html);

load returns a store path for the files. The second argument to renderToString is passed to the page as its inputs. Running node render.js prints the HTML:

Output
<!doctype html><html lang="en"><head><title>Hello, Nix… (truncated)

A loaded path can be rendered any number of times. unload releases it.