# nifra site (Solid)

A nifra + **Solid** SSR site - file-based routes, typed loaders/actions, hydration - that deploys to
**Bun, Node (Docker), Deno Deploy, Cloudflare Pages, and Vercel Edge from one source**. `app.fetch`
is Web-standard, so only the server entry + build target differ per platform.

```sh
bun install
bun run dev        # nifra dev → true-HMR dev server (Bun + nifra SSR) at http://localhost:3000
bun run preview    # wrangler pages dev dist → preview the built Cloudflare bundle (run `bun run build` first)
```

The backend starter includes response security headers, explicit-origin CORS, a 30-second request
deadline, bounded concurrency, and a development rate limit. Its in-memory rate-limit store refuses
production unless `NIFRA_ALLOW_MEMORY_RATE_LIMIT=true`; use a shared store for multi-instance deploys.
For cookie sessions, add signed CSRF middleware and require both runtime authentication and CSRF
evidence in `nifra.assurance.ts`.

Routes are Solid function components (JSX, compiled by `solidBunPlugin`) under `routes/` - `index.tsx`
(landing + a live loader/action counter), `_layout.tsx` (chrome), `_404.tsx`. The frontend adapter is
one line in `framework.ts`; data lives behind `backend.ts`. Each `build*` script wires
`solidBunPlugin("dom")` for the client and `("ssr")` + the `solid` export condition for the server.

## Deploy - pick a target

| target | build | deploy |
| --- | --- | --- |
| **Bun** (flagship) | `bun run build:bun` | `bun run start` - any host |
| **Node** | `bun run build:node` | `docker build -t app . && docker run -p 3000:3000 app` (or `bun run start:node`) |
| **Deno Deploy** | `bun run build:deno` | `deployctl deploy --prod --entrypoint=dist-deno/server-deno.js` |
| **Cloudflare Pages** | `bun run build` | `bun run deploy:cf` |
| **Vercel Edge** | `bun run build:vercel` | `bun run deploy:vercel` |

nifra never enters your cloud credentials - it scaffolds the configs (`Dockerfile`, `deno.json`,
`wrangler.toml`, Vercel Build Output API); you run the vendor CLI.

## Structure

```
routes/        index.tsx (landing), _layout.tsx (chrome), _404.tsx
framework.ts   the adapter (solidAdapter) - imported by the server entries (edge-bundlable)
nifra.config.ts the nifra CLI's dev/build config (adapter + clientModule + Solid plugins) - read by `nifra dev`
backend.ts     your contract (loaders/actions call it in-process)
server-bun.ts  Bun entry (Bun.serve)         build-bun.ts    → dist-bun/
_worker.ts     Cloudflare Pages entry        build.ts        → dist/
server-node.ts Node entry (@nifrajs/node)       build-node.ts   → dist-node/   (Dockerfile)
server-deno.ts Deno entry (@nifrajs/deno)       build-deno.ts   → dist-deno/    (deno.json)
server-vercel.ts Vercel Edge function        build-vercel.ts → .vercel/output/
```
