feat: close remaining gaps — middleware, demo wiring, error UX, env validation
CI / lint + typecheck + test + build (push) Canceled after 0s
CI / lint + typecheck + test + build (push) Canceled after 0s
- Auth: middleware.ts guards /protected via better-auth session cookie; protected page reads session server-side (auth.api.getSession) - Demo wiring (app/demo + components/demo): react-markdown + remark-gfm + shiki CodeBlock, RHF+zod form with react-query mutation + sonner toast, react-table items list (legacy API, table v9), /api/items GET+POST (zod v4 coercion, schema in lib/items.ts shared with unit tests) - Error UX: app/error.tsx (retry + digest), not-found.tsx (404), loading.tsx - Env: lib/env.ts zod-validated (no import-time throw), .env.example sync (NEXT_PUBLIC_BETTER_AUTH_URL), auth-client uses env - Tooling: @vitest/coverage-v8 (test:coverage works), tsconfig cleanup (drop .next/dev/dev/types artifact), README rewrite, demo e2e specs
This commit is contained in:
@@ -1,36 +1,117 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
# Next.js Template
|
||||
|
||||
## Getting Started
|
||||
Production-ready Next.js 16 (App Router, Turbopack) starter on Bun, with
|
||||
shadcn/ui Base UI components, TypeScript strict, and a zero-warning
|
||||
lint/typecheck/test/build pipeline.
|
||||
|
||||
First, run the development server:
|
||||
## Stack
|
||||
|
||||
- **Framework:** Next.js 16.3 (App Router, Turbopack, standalone output)
|
||||
- **Runtime:** Bun 1.3.14
|
||||
- **UI:** shadcn/ui Base-Nova (Base UI) + Tailwind CSS v4, lucide-react, motion
|
||||
- **Data:** @tanstack/react-query, @tanstack/react-table
|
||||
- **Forms:** react-hook-form + zod (v4) + @hookform/resolvers
|
||||
- **Auth:** better-auth (memory adapter, swap to Drizzle/Postgres when ready)
|
||||
- **API client:** openapi-fetch + openapi-typescript, ky
|
||||
- **Markdown:** react-markdown + remark-gfm + shiki (server-side highlighting)
|
||||
- **Misc:** zustand, nuqs, sonner, cmdk, vaul, embla-carousel-react, date-fns,
|
||||
next-themes, recharts
|
||||
|
||||
## Getting started
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
bun install
|
||||
cp .env.example .env # optional: set BETTER_AUTH_SECRET / BETTER_AUTH_URL
|
||||
bun run dev # http://localhost:3000
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Requires Node ≥ 18 (Bun runtime) — see `packageManager` in package.json.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
## Scripts
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
| Script | Description |
|
||||
| --------------------------------- | ------------------------------------------------------------------- |
|
||||
| `bun run dev` | Start dev server (Turbopack, NODE_ENV pinned to development) |
|
||||
| `bun run build` | Production build (standalone output for Docker) |
|
||||
| `bun run start` | Serve the production build |
|
||||
| `bun run lint` | ESLint (next core-web-vitals + typescript) |
|
||||
| `bun run lint:fix` | ESLint with autofix |
|
||||
| `bun run typecheck` | `tsc --noEmit` (strict + noUnusedLocals/Parameters) |
|
||||
| `bun run test` | Vitest unit tests (jsdom + jest-dom) |
|
||||
| `bun run test:watch` | Vitest watch mode |
|
||||
| `bun run test:coverage` | Vitest with v8 coverage report |
|
||||
| `bun run test:e2e` | Playwright E2E (Chromium, dedicated :3100) |
|
||||
| `bun run format` / `format:check` | Prettier write / check (Tailwind v4 plugin) |
|
||||
| `bun run api:generate` | Regenerate `types/api.ts` from `/api/openapi` (dev server must run) |
|
||||
| `bun run prepare` | Install husky hooks |
|
||||
|
||||
## Learn More
|
||||
Git hooks (husky + lint-staged) run ESLint + Prettier on staged files.
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
## Project structure
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
```
|
||||
app/
|
||||
page.tsx # landing page
|
||||
demo/ # wiring example: markdown+shiki, form, table, session
|
||||
protected/ # route guarded by middleware (better-auth session)
|
||||
error.tsx / loading.tsx / not-found.tsx
|
||||
api/
|
||||
health/ # GET health JSON
|
||||
openapi/ # OpenAPI 3.1 spec for codegen
|
||||
auth/[...all]/ # better-auth handler
|
||||
items/ # GET list / POST create (zod-validated)
|
||||
components/
|
||||
providers.tsx # QueryClient + Theme + Nuqs + Tooltip + Sonner
|
||||
ui/ # shadcn Base-Nova components (CLI-managed)
|
||||
demo/ # form + table wiring examples
|
||||
hooks/ # use-mobile (useSyncExternalStore)
|
||||
lib/
|
||||
auth.ts # better-auth server (memory adapter)
|
||||
auth-client.ts # better-auth react client
|
||||
api.ts # typed openapi-fetch client
|
||||
http.ts # ky wrapper
|
||||
query-client.ts # react-query client (per-request on server)
|
||||
env.ts # zod-validated env (no import-time throw)
|
||||
types/api.ts # generated openapi-typescript types
|
||||
middleware.ts # auth route guard
|
||||
e2e/ # Playwright specs
|
||||
.github/workflows/ci.yml
|
||||
Dockerfile # multi-stage standalone build
|
||||
```
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
## Auth
|
||||
|
||||
## Deploy on Vercel
|
||||
better-auth is wired but intentionally runs on the in-memory adapter so the
|
||||
template builds without a database.
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
1. `bunx @better-auth/cli secret` → put the result in `BETTER_AUTH_SECRET`.
|
||||
2. Set `BETTER_AUTH_URL` (+ `NEXT_PUBLIC_BETTER_AUTH_URL` for the client).
|
||||
3. To persist users, swap `memoryAdapter({})` in `lib/auth.ts` for a real
|
||||
adapter (e.g. `drizzleAdapter(db, { provider: "pg" })`) and add the DB URL.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
Routes under `/protected` require a session (see `middleware.ts`).
|
||||
|
||||
## OpenAPI + typed client
|
||||
|
||||
`app/api/openapi` serves an OpenAPI 3.1 document. Regenerate the typed client:
|
||||
|
||||
```bash
|
||||
bun run dev & # server must be up
|
||||
bun run api:generate # writes types/api.ts
|
||||
```
|
||||
|
||||
Then use `lib/api.ts` (`createClient<paths>` from openapi-fetch).
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
docker build -t nextjs-template .
|
||||
docker run -p 3000:3000 nextjs-template
|
||||
```
|
||||
|
||||
Multi-stage standalone image (~50MB runtime); runs as non-root user; requires
|
||||
NODE_ENV=production and the env vars above at runtime.
|
||||
|
||||
## License
|
||||
|
||||
Private template.
|
||||
|
||||
Reference in New Issue
Block a user