# sitelo
> Zero-config static site generation powered by Vite and vite-plugin-html-pages
The whole of https://sitelo.dev as Markdown: the guides, the component reference and the examples, in the order the site lists them. https://sitelo.dev/llms.txt is the shorter index, and each page below also has a copy of its own at the URL above it.
---
URL: https://sitelo.dev/docs
# Getting started
> Install sitelo and build your first static site.
sitelo is a zero-config static site generator powered by Vite. Install one package, write functions that return HTML, and run `sitelo build`.
## Install
`shell`
```bash
npm install -D sitelo
```
Requires Node 20.19+ (or 22.12+). Vite is bundled — you do not install it separately.
## Your first page
Create `src/index.ht.js` (or `.ht.jsx`). [ht.js](https://ht.js.org) is recommended:
`src/index.ht.js — Template literal`
```javascript
export default () => `
My website
Hello world
`
```
`src/index.ht.js — ht.js (recommended)`
```javascript
import { html, head, title, body, h1 } from 'javascript-to-html'
export default () =>
html({ lang: 'en' },
head(title('My website')),
body(h1('Hello world'))
)
```
`src/index.ht.jsx — JSX`
```jsx
export default function Home() {
return (
My website
Hello world
)
}
```
## Run
`shell`
```bash
sitelo # dev server
sitelo build # write dist/
sitelo preview # preview the build
```
That emits `dist/index.html` (with `` added for you) plus a default `404.html`.
## Next
- [Writing pages](https://sitelo.dev/docs/pages) — template strings, JSX, structured modules
- [Routing](https://sitelo.dev/docs/routing) — file-based routes and `generateStaticParams`
- [Data loading](https://sitelo.dev/docs/data) — `data()` and `fetchWithCache`
- [Assets & styling](https://sitelo.dev/docs/assets) — frontend JS/CSS compiled by Vite (`src/js`, `src/css`)
- [Configuration](https://sitelo.dev/docs/configuration) — `sitelo.config.js` and Vite options
- [Build with AI](https://sitelo.dev/docs/build-with-ai) — `llms.txt`, project rules, and agent tips
---
URL: https://sitelo.dev/docs/pages
# Writing pages
> How to author sitelo pages — template literals, ht.js (recommended), or JSX.
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 ``, sitelo prepends `` automatically. Prefer [ht.js](https://ht.js.org) (`javascript-to-html`) for markup — tag functions that return strings, with no templating engine or React runtime.
## A function returning HTML
`page.ht.js — Template literal`
```javascript
export default ({ params, data, dev }) => `
Hello
`
```
`page.ht.js — ht.js (recommended)`
```javascript
import { html, body, h1 } from 'javascript-to-html'
export default ({ params, data, dev }) =>
html(
body(h1('Hello'))
)
```
`page.ht.jsx — JSX`
```jsx
export default function Page({ params, data, dev }) {
return (
Hello
)
}
```
JSX files use `*.ht.jsx` / `*.ht.tsx` and need `react` + `react-dom` installed. See [JSX limitations](https://sitelo.dev/docs/pages#jsx-limitations) below — sitelo turns JSX into static HTML at build time; it is not a React app in the browser.
## A plain string
`page.ht.js`
```javascript
export default `Static as it gets
`
```
## A structured module
Keep `render`, `data`, and `generateStaticParams` together:
`page.ht.js — Template literal`
```javascript
export default {
generateStaticParams: () => [{ slug: 'hello' }],
data: ({ params }) => ({ title: params.slug }),
render: ({ data }) => `${data.title}
`,
}
```
`page.ht.js — ht.js (recommended)`
```javascript
import { html, body, h1 } from 'javascript-to-html'
export default {
generateStaticParams: () => [{ slug: 'hello' }],
data: ({ params }) => ({ title: params.slug }),
render: ({ data }) =>
html(
body(h1(data.title))
),
}
```
`page.ht.jsx — JSX`
```jsx
export default {
generateStaticParams: () => [{ slug: 'hello' }],
data: ({ params }) => ({ title: params.slug }),
render: ({ data }) => (
{data.title}
),
}
```
## 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:
- Event handlers (`onClick`, `onChange`, …) do nothing in the finished site — nothing is listening. The dev server warns if it finds them.
- Hooks (`useState`, `useEffect`, …) are not part of the shipped page. They may run once during the build render; they do not keep state in the browser.
- Browser-only APIs (`window`, `document`) are unavailable while the page is rendered at build time.
- `dangerouslySetInnerHTML` works for injecting HTML strings; interactivity still needs a separate client `