Writing pages

Any file ending in a page extension is a page. Default extensions: .ht.js, .html.js, and the TypeScript / JSX variants (.ht.ts, .ht.tsx, …).

If output starts with <html>, sitelo prepends <!DOCTYPE html> automatically. Prefer ht.js (javascript-to-html) for markup — tag functions that return strings, with no templating engine or React runtime.

1. A function returning HTML

JSX files use *.ht.jsx / *.ht.tsx and need react + react-dom installed. See JSX limitations below — sitelo turns JSX into static HTML at build time; it is not a React app in the browser.

2. A plain string

export default `<html><body><h1>Static as it gets</h1></body></html>`

3. A structured module

Keep render, data, and generateStaticParams together:

JSX limitations

sitelo can render .ht.jsx / .ht.tsx pages with react-dom/server so you can write familiar JSX syntax. That is an authoring convenience — not a React application.

React is built for the browser: a component tree that mounts, hydrates, and responds to events. sitelo never ships that runtime with your pages. At build time it renders your JSX to an HTML string, writes the file, and stops. There is no client React bundle, no hydration, and no virtual DOM waiting in the browser.

Because of that:

For clicks, forms, and other client behavior, link a normal script through the asset pipeline, or use server islands for request-time HTML. Prefer ht.js or template literals when you don’t need JSX syntax — no React install, and the model matches “HTML at build time.”

Render context

Every page function receives one argument:

params

Route params for this page (Record<string, string | string[]>).

data

Whatever your data() function returned.

page

Route metadata (routePath, relativePath, …).

dev

true in the dev server, false at build time.