Documentation
Templates & layouts
TinyJS uses server-side TSX as a typed template language and composes layouts structurally through the route tree.
TSX is syntax in TinyJS, not a browser architecture. There is no React, DOM, virtual DOM, hydration, or client runtime.
A page template
A template receives the selected page, site configuration, navigation, a Markdown helper, an asset helper, and related rendering context through PageProps.
import type { PageProps } from '@carl.fyi/tinyjs'
export default function DefaultTemplate({ markdown, page }: PageProps) {
return (
<article>
<h1>{page.title}</h1>
{page.content ? <p>{page.content}</p> : null}
{page.markdown ? markdown(page.markdown) : null}
</article>
)
}
A root layout
A layout is an ordinary server-side function. The root layout typically supplies the complete HTML document:
import type { LayoutProps } from '@carl.fyi/tinyjs'
export default function Layout({ children, site }: LayoutProps) {
return (
<html lang="en">
<head><title>{site.name}</title></head>
<body><main>{children}</main></body>
</html>
)
}
Structural nesting
Layouts are never opening and closing siblings. TinyJS first resolves the selected page template, passes that result to the nearest layout.tsx as children, then repeats the operation up to the root layout.
For /work/project, the result is structurally equivalent to:
<SiteLayout>
<WorkLayout>
<ProjectTemplate page={page} />
</WorkLayout>
</SiteLayout>
This keeps each route branch independent while guaranteeing well-formed nesting.