diff --git a/CLAUDE.md b/CLAUDE.md index 83e5b0a..03dee9c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,11 +40,21 @@ bunext start # Start production server from pre-built artifacts - `src/presets/` — Default 404/500 components and sample `bunext.config.ts` ### Page module contract -Pages live in `src/pages/`. A page file may export: -- Default export: React component receiving `ServerProps | StaticProps` -- `server`: `BunextPageServerFn` — runs server-side before rendering, return value becomes props +Pages live in `src/pages/`. Server logic is **separated from page files** into companion `.server.ts` / `.server.tsx` files to avoid bundling server-only code into the client. + +**Page file** (`page.tsx`) — client-safe exports only (bundled to the browser): +- Default export: React component receiving props from the server file - `meta`: `BunextPageModuleMeta` — SEO/OG metadata -- `head`: ReactNode — extra `
` content +- `Head`: FC — extra `` content +- `config`: `BunextRouteConfig` — cache settings +- `html_props`: `BunextHTMLProps` — attributes on the `` element + +**Server file** (`page.server.ts` or `page.server.tsx`) — server-only, never sent to the browser: +- Default export or `export const server`: `BunextPageServerFn` — runs server-side before rendering, return value becomes props + +The framework resolves the companion by replacing the page extension with `.server.ts` or `.server.tsx`. If neither exists, no server function runs and only the default `url` prop is injected. + +`__root.tsx` follows the same contract; its server companion is `__root.server.ts`. API routes live in `src/pages/api/` and follow standard Bun `Request → Response` handler conventions. diff --git a/README.md b/README.md index 64df12c..d336eeb 100644 --- a/README.md +++ b/README.md @@ -199,16 +199,19 @@ A typical Bunext project has the following layout: my-app/ ├── src/ │ └── pages/ # File-system routes (pages and API handlers) -│ ├── __root.tsx # Optional: root layout wrapper for all pages -│ ├── index.tsx # Route: / -│ ├── about.tsx # Route: /about -│ ├── 404.tsx # Optional: custom 404 page -│ ├── 500.tsx # Optional: custom 500 page +│ ├── __root.tsx # Optional: root layout wrapper for all pages +│ ├── __root.server.ts # Optional: root-level server logic +│ ├── index.tsx # Route: / +│ ├── index.server.ts # Optional: server logic for index route +│ ├── about.tsx # Route: /about +│ ├── 404.tsx # Optional: custom 404 page +│ ├── 500.tsx # Optional: custom 500 page │ ├── blog/ -│ │ ├── index.tsx # Route: /blog -│ │ └── [slug].tsx # Route: /blog/:slug (dynamic) +│ │ ├── index.tsx # Route: /blog +│ │ ├── index.server.ts # Server logic for /blog +│ │ └── [slug].tsx # Route: /blog/:slug (dynamic) │ └── api/ -│ └── users.ts # API route: /api/users +│ └── users.ts # API route: /api/users ├── public/ # Static files served at /public/* ├── .bunext/ # Internal build artifacts (do not edit manually) │ └── public/ @@ -275,19 +278,15 @@ export default function HomePage() { ### Server Function -Export a `server` function to run server-side logic before rendering. The return value's `props` field is spread into the page component as props, and `query` carries route query parameters. +Server logic lives in a companion **`.server.ts`** (or `.server.tsx`) file alongside the page. The framework looks for `