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.

export default function Page() {
  return <h1>Hello</h1>;
}

loader

Optional. Async function to load data on the server.

export async function loader(args: LoaderArgs): Promise<Data>;

action

Optional. Async function to handle non-GET requests.

export async function action(args: ActionArgs): Promise<Data>;

config

Optional. Configuration object for the route.

export const config = {
  mode: "static" | "app" // default: "static"
};

ErrorBoundary

Optional. Component to render when an error occurs in this route or its children.

export function ErrorBoundary() {
  return <h1>Something went wrong</h1>;
}

headers

Optional. Function to set HTTP headers for the response.

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.

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.