# App Routes

App mode is for routes whose response depends on the request or whose interface
needs the client router. Neutron runs matching middleware and loaders on the
server, renders HTML, then hydrates the route in the browser.

```tsx
export const config = { mode: "app" };
```

After the initial document load, links between app routes use client-side
navigation. A project can mix app routes with [static routes](/docs/routing/static-routes);
navigation to a static route remains a browser-native document navigation.

## Load server data

Matching layout and page loaders run in parallel. Their return values are
serialized for the route components:

```tsx
import { useLoaderData } from "@neutron-build/core";

export const config = { mode: "app" };

export async function loader({ request }) {
  return { user: await getUser(request) };
}

export default function Profile() {
  const { user } = useLoaderData<typeof loader>();
  return <h1>Hello, {user.name}</h1>;
}
```

Keep credentials and private services inside loaders and actions; those
exports are stripped from the client build.

## Handle mutations

An `action` handles non-GET submissions for the matched route:

```tsx
import { Form } from "@neutron-build/core";

export const config = { mode: "app" };

export async function action({ request }) {
  const form = await request.formData();
  await updateName(form.get("name"));
  return { saved: true };
}

export default function Settings() {
  return (
    <Form method="post">
      <input name="name" />
      <button>Save</button>
    </Form>
  );
}
```

See [Loaders](/docs/data/loaders), [Actions](/docs/data/actions), and
[Forms](/docs/data/forms).

## Client entry

The generated `src/main.tsx` registers the shared route table and starts
hydration:

```tsx
import { init, registerRoutes } from "@neutron-build/core/client";
import { routes } from "virtual:neutron/routes";

registerRoutes(routes);
void init();
```

The starter creates this file. Add browser-only setup before `init()` when
needed; removing the entry disables hydration and client navigation.

## Runtime

Preact is the default. Projects that need React package compatibility can use
the `react-compat` runtime when they are created:

```bash
npm create neutron@latest my-app -- --runtime react-compat
```

The runtime setting is project-wide; the static/app decision is per route.
