import type { ActionArgs, LoaderArgs, LoaderData } from "@nifrajs/client" import type { backend } from "../backend" export const meta = { title: "nifra site", meta: [{ name: "description", content: "A nifra + React SSR site, deployable to every runtime." }], } // Loader runs on the server (in-process during SSR). The action handles the form POST; after a // client submit the loader revalidates with no full reload (progressive enhancement). export async function loader({ api }: LoaderArgs) { const res = await api.count.get() return { count: res.ok ? res.data.count : 0 } } export async function action({ api }: ActionArgs) { await api.count.post() return { ok: true } } export default function Home(props: { data: LoaderData }) { return ( <>

Your nifra app,
everywhere.

SSR + hydration, end-to-end types, React. One source - deploy to Cloudflare Pages, Node, Deno, or Vercel Edge. Edit routes/index.tsx to begin.

Live full-stack loop

Count is rendered by a typed loader, incremented by an action, revalidated with no full reload.

{props.data.count}
) }