Skip to content

Your first page

A Reactra page is a component block. The scaffold’s home page is a counter — let’s read it line by line. It lives at src/pages/index.tsx:

import styles from "./index.module.css"
export component HomePage {
meta { title: "My App" }
state count: number = 0
derived label = count === 1 ? "1 click" : `${count} clicks`
action inc() { count = count + 1 }
view {
<main className={styles.app}>
<h1>Welcome to Reactra</h1>
<p>{label}</p>
<button type="button" onClick={inc}>click me</button>
</main>
}
}
Compiled React 19 — this is the file in your repo
import styles from "./index.module.css"
import { useCallback, useEffect, useMemo, useState } from "react"
export const HomePage = () => {
const [count, setCount] = useState((0) as number)
const label = useMemo(() => count === 1 ? "1 click" : `${count} clicks`, [count])
const inc = useCallback(() => { setCount(prev => prev + 1) }, [])
const __meta = { title: "My App" }
useEffect(() => { if (typeof document !== "undefined" && __meta.title != null) document.title = String(__meta.title) }, [__meta.title])
useEffect(() => { const h = globalThis.__REACTRA_TEST__; if (h) h.update("HomePage", { count, label, inc }) })
return (<>
<main className={styles.app}>
<h1>Welcome to Reactra</h1>
<p>{label}</p>
<button type="button" onClick={inc}>click me</button>
</main>
</>)
}
export default HomePage
  • state declares reactive local state. state count: number = 0 compiles to a useState. Writing count = count + 1 (inside an action) is a real assignment in the DSL — the compiler turns it into the setter call.
  • derived is computed state. label recomputes whenever count changes; you never call it, you read it. It compiles to a plain expression (no useMemo unless it pays for itself).
  • action is an event handler / mutation. inc() is wired to onClick in the view. Inside an action, assignments to state are reactive writes.
  • view is the JSX the component renders. It’s ordinary React JSX with the component’s state/derived/action names in scope.

meta { title: "My App" } sets the document title for this route. It accepts a template string, so it can interpolate state: meta { title: \${count} clicks` }`.

The file’s path is its route. src/pages/index.tsx/. Drop a new file at src/pages/about.tsx and it’s automatically routed to /about — no route config to edit. Dynamic segments use brackets: src/pages/users/[id].tsx/users/:id, and id is available as a param.

See Project structure for the full layout, and the Guide for the rest of the component surface.