Написание страниц
На этой странице
Любой файл с расширением страницы является страницей. Расширения по умолчанию: .ht.js, .html.js, а также варианты TypeScript и JSX (.ht.ts, .ht.tsx, …).
Если вывод начинается с <html>, sitelo автоматически добавляет <!DOCTYPE html>. Для разметки рекомендуем ht.js (javascript-to-html): функции-теги, возвращающие строки, без шаблонизатора и без рантайма React.
1. Функция, возвращающая HTML
export default ({ params, data, dev }) => `
<html>
<body><h1>Привет</h1></body>
</html>
`import { html, body, h1 } from 'javascript-to-html'
export default ({ params, data, dev }) =>
html(
body(h1('Привет'))
)export default function Page({ params, data, dev }) {
return (
<html>
<body><h1>Привет</h1></body>
</html>
)
}JSX-файлы используют *.ht.jsx / *.ht.tsx и требуют установленных react и react-dom. См. ограничения JSX ниже — sitelo превращает JSX в статический HTML во время сборки; это не React-приложение в браузере.
2. Обычная строка
export default `<html><body><h1>Статичнее некуда</h1></body></html>`3. Структурированный модуль
Держите render, data и generateStaticParams рядом:
export default {
generateStaticParams: () => [{ slug: 'hello' }],
data: ({ params }) => ({ title: params.slug }),
render: ({ data }) => `<html><body><h1>${data.title}</h1></body></html>`,
}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))
),
}export default {
generateStaticParams: () => [{ slug: 'hello' }],
data: ({ params }) => ({ title: params.slug }),
render: ({ data }) => (
<html>
<body><h1>{data.title}</h1></body>
</html>
),
}Ограничения JSX
sitelo умеет рендерить страницы .ht.jsx / .ht.tsx через react-dom/server, так что вы можете писать привычным синтаксисом JSX. Это удобство записи — а не React-приложение.
React создан для браузера: дерево компонентов, которое монтируется, гидратируется и реагирует на события. sitelo никогда не отправляет этот рантайм вместе с вашими страницами. Во время сборки он рендерит ваш JSX в строку HTML, записывает файл и на этом останавливается. Ни клиентского бандла React, ни гидратации, ни виртуального DOM, ждущего в браузере.
Из-за этого:
- Обработчики событий (
onClick,onChange, …) на готовом сайте ничего не делают — их некому слушать. Сервер разработки предупредит, если найдёт их. - Хуки (
useState,useEffect, …) не попадают на опубликованную страницу. Они могут выполниться один раз при рендеринге во время сборки, но состояние в браузере не хранят. - Браузерные API (
window,document) недоступны, пока страница рендерится во время сборки. dangerouslySetInnerHTMLработает для вставки строк HTML; интерактивности всё равно нужен отдельный клиентский<script>.
Для кликов, форм и прочего клиентского поведения подключите обычный скрипт через конвейер ресурсов, либо используйте серверные острова для HTML, создаваемого в момент запроса. Когда синтаксис JSX не нужен, лучше взять ht.js или шаблонные строки — без установки React, и модель совпадает с «HTML во время сборки».
Контекст рендеринга
Каждая функция страницы получает один аргумент:
params
Параметры маршрута этой страницы (Record<string, string | string[]>).
data
То, что вернула ваша функция data().
page
Метаданные маршрута (routePath, relativePath, …).
dev
true в сервере разработки, false во время сборки.