# Route Exports

Route files in `src/routes` can export the following named exports.

## `default` (Component)

**Required**. The React/Preact component to render for this route.

```tsx
export default function Page() {
  return <h1>Hello</h1>;
}
```

## `loader`

**Optional**. Async function to load data on the server.

```tsx
export async function loader(args: LoaderArgs): Promise<Data>;
```

## `action`

**Optional**. Async function to handle non-GET requests.

```tsx
export async function action(args: ActionArgs): Promise<Data>;
```

## `config`

**Optional**. Configuration object for the route.

```tsx
export const config = {
  mode: "static" | "app" // default: "static"
};
```

## `ErrorBoundary`

**Optional**. Component to render when an error occurs in this route or its children.

```tsx
export function ErrorBoundary() {
  return <h1>Something went wrong</h1>;
}
```

## `headers`

**Optional**. Function to set HTTP headers for the response.

```tsx
export function headers({ loaderHeaders, parentHeaders }) {
  return {
    "Cache-Control": "max-age=3600",
  };
}
```

## `head`

**Optional**. Function to set the document `<head>` — title, meta tags, and
`<link>` tags. It receives the route's `data` (plus `params`, `pathname`,
`request`, `context`) and returns an SEO object.

```tsx
export function head({ data }) {
  return {
    title: data.post.title,
    description: data.post.excerpt,
    canonical: `https://example.com/blog/${data.post.slug}`,
    openGraph: { image: data.post.cover },
    // Arbitrary <link> tags: favicon, preconnect, manifest, alternate…
    link: { rel: "icon", type: "image/svg+xml", href: "/favicon.svg" },
  };
}
```

Supported fields: `title`, `titleTemplate` (e.g. `"%s — My Site"`, usually set on
a layout so child routes inherit it), `description`, `canonical`, `keywords`,
`noindex`, `openGraph`, `twitter`, `jsonLd`, `link`, `headScripts`, `htmlAttrs`,
`bodyAttrs`. A layout's `head()` and a route's `head()` merge — the route wins
per field, while `link`, `headScripts`, and `jsonLd` are concatenated.
