> ## Documentation Index
> Fetch the complete documentation index at: https://better-router.bansal.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Project structure

> Default folders inside src and what better-router does with each one.

Keep routes and middleware under `src`. Everything else is optional until you need it.

```
src/
  routes/                    # pages and API routes
    _document.tsx            # HTML document (title, CSS, fonts)
    _layout.tsx              # root layout (nav, chrome)
    _layout.server.tsx       # optional loader for the root layout
    _error.tsx               # uncaught errors
    _404.tsx                 # unmatched routes
    _middleware.ts           # nested middleware for /
    index.tsx                # GET /
    index.server.tsx         # loader / action for /
    about.tsx                # GET /about
    guide.mdx                # GET /guide (markdown page)
    users/
      _layout.tsx            # wraps /users/*
      [id].tsx               # GET /users/:id
      [id].server.tsx
    blog/
      index.island.tsx       # island page
      _Counter.tsx           # not a route (_ prefix)
    api/
      hello.ts               # GET /api/hello
      webhooks/
        stripe.ts            # POST /api/webhooks/stripe
  components/
    markdown/                # auto-registered MDX components
      Callout.tsx
  middleware/                # global Hono middleware, sorted by name
    01.logger.ts
  worker.ts                  # Cloudflare: fetch / scheduled / queue / email
public/                      # copied to dist/client as-is
.env                         # local Node / Vite secrets (gitignored)
.dev.vars                    # local Wrangler secrets
wrangler.jsonc               # Cloudflare deploy + bindings
vite.config.ts
```

Generated at runtime (gitignored):

```
.better-router/manifest.json # route manifest from the client build
```

## Conventions

| Location                     | Role                                                            |
| ---------------------------- | --------------------------------------------------------------- |
| `src/routes/**/*.tsx`        | React page. Default export is the component.                    |
| `src/routes/**/*.{md,mdx}`   | Markdown page. Same routing as `.tsx`.                          |
| `src/components/markdown`    | React components mapped into markdown pages.                    |
| `src/routes/**/*.island.tsx` | Island page. Static HTML plus selective hydration.              |
| `src/routes/**/*.server.tsx` | Server-only loaders, actions, and flags.                        |
| `src/routes/**/*.ts`         | API route. Export `GET`, `POST`, and other HTTP methods.        |
| `src/routes/_layout.tsx`     | Layout for the directory and its children.                      |
| `src/routes/_document.tsx`   | HTML shell. Put `<title>`, fonts, and CSS here.                 |
| `src/routes/_error.tsx`      | Error page. Receives `{ error, status }`.                       |
| `src/routes/_404.tsx`        | Not-found page.                                                 |
| `src/middleware`             | Global Hono middleware, sorted by file name.                    |
| `src/worker.ts`              | Cloudflare Worker entrypoint. See [Worker entrypoint](/worker). |
| `public/`                    | Favicon, robots.txt, static files.                              |

Files and folders that start with `_` are not routes. `_layout.tsx`, `_document.tsx`, `_error.tsx`, `_404.tsx`, and `_middleware.ts` are special files. Use `_Button.tsx` for colocated components.

Directories wrapped in parentheses are groups. `(marketing)/about.tsx` still maps to `/about`.

## Required vs optional

You can ship a site with only `src/routes` and `src/middleware`. Add `src/worker.ts` and `wrangler.jsonc` when you deploy to Cloudflare — the plugin then infers `target: "cloudflare"`. Node apps do not need either file.
