Skip to content
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: "Data fetching"
version: "1.0"
---

Fetching data from a remote API or database is a core task for most applications.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: "Data mutation"
version: "1.0"
---

Mutating data on a server is a common task in most applications.
Expand Down
98 changes: 0 additions & 98 deletions src/routes/solid-start/(2)migrating-from-v1.mdx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: Routing
use_cases: >-
page navigation, url structure, dynamic paths, route organization,
filesystem routing, api endpoints
tags:
- routing
- filesystem
- pages
- dynamic
- api
version: "2.0"
description: >-
SolidStart v2 routing uses the filesystem router to map files in
src/routes to UI routes and API routes.
---

Routes come from the filesystem.
`FileRoutes` from `@solidjs/start/router` maps files in `src/routes` into route paths.

This page covers the route filename conventions.

## UI routes and API routes

There are two route shapes:

- Files with a default export become UI routes.
- Files that export HTTP method names such as `GET` or `POST` become API routes.

You can read more about handler exports in [API routes](/v2/solid-start/building-your-application/api-routes).

## Basic filename mapping

File names map to paths using these rules:

- `src/routes/index.tsx` becomes `/`
- `src/routes/about.tsx` becomes `/about`
- `src/routes/blog/index.tsx` becomes `/blog`
- `src/routes/blog/post.tsx` becomes `/blog/post`

An `.mdx` file in `src/routes` is also treated as a page route.

## Dynamic segments

Bracketed segments become route params:

- `src/routes/users/[id].tsx` becomes `/users/:id`
- `src/routes/users/[[id]].tsx` becomes `/users/:id?`
- `src/routes/docs/[...slug].tsx` becomes `/docs/*slug`

Read them with [`useParams`](/solid-router/reference/primitives/use-params):

```tsx title="src/routes/users/[id].tsx"
import { useParams } from "@solidjs/router";

export default function UserPage() {
const params = useParams();
return <h1>User {params.id}</h1>;
}
```

## Route config exports

The filesystem router also looks for an exported `route` object alongside a page component.
That lets a route file attach route-level behavior while still default-exporting UI.

```tsx title="src/routes/posts/[id].tsx"
import { query, createAsync, type RouteDefinition } from "@solidjs/router";

const getPost = query(async (id: string) => {
"use server";
const response = await fetch(`https://example.com/api/posts/${id}`);
return response.json();
}, "post");

export const route = {
preload: ({ params }) => getPost(params.id),
} satisfies RouteDefinition;

export default function PostPage(props: { params: { id: string } }) {
const post = createAsync(() => getPost(props.params.id));
return <pre>{JSON.stringify(post(), null, 2)}</pre>;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: API routes
use_cases: >-
rest api, webhooks, oauth callbacks, server endpoints, route handlers,
request handling
tags:
- api
- http
- server
- handlers
- endpoints
version: "2.0"
description: >-
SolidStart v2 API routes are filesystem routes that export HTTP method
handlers and receive typed APIEvent objects from @solidjs/start/server.
---

Use an API route when you need a route that returns data or handles incoming HTTP requests instead of rendering page UI.

A file becomes an API route when it exports one or more HTTP method names such as [`GET`](/v2/solid-start/reference/server/get), `POST`, `PATCH`, or `DELETE`.

## Create an API route

An API route lives in `src/routes` and exports handler functions named after the HTTP methods it handles.

```tsx title="src/routes/api/ping.ts"
export function GET() {
return new Response("pong");
}
```

The package exports `APIEvent` from `@solidjs/start/server`.
That type includes:

- `request` for the incoming `Request`
- `params` for dynamic path parameters
- `response` for the mutable response stub
- `locals` for request-scoped locals
- `nativeEvent` for the underlying H3 event

```tsx title="src/routes/api/users/[id].ts"
import type { APIEvent } from "@solidjs/start/server";

export async function GET({ params }: APIEvent) {
return Response.json({ userId: params.id });
}
```

## File naming follows the same router

API routes use the same path conventions as UI routes.
For example:

- `src/routes/api/users.ts` becomes `/api/users`
- `src/routes/api/users/[id].ts` becomes `/api/users/:id`
- `src/routes/api/files/[...slug].ts` becomes `/api/files/*slug`

## HEAD fallback

If a route exports `GET` but not `HEAD`, `HEAD` requests are handled by the `GET` handler.
Export `HEAD` explicitly when you need custom behavior.

## Request helpers

Cookie, session, header, and request helpers are exported from `@solidjs/start/http`.

```tsx title="src/routes/api/session.ts"
import { getCookie } from "@solidjs/start/http";
import type { APIEvent } from "@solidjs/start/server";

export function GET(_event: APIEvent) {
const userId = getCookie("userId");
if (!userId) {
return new Response("Not logged in", { status: 401 });
}

return Response.json({ userId });
}
```

## When to use an API route

API routes are a good fit when you need:

- endpoints for other clients
- webhook receivers
- auth callback handlers
- routes that return non-HTML responses

If the data is only needed by your route UI, prefer [Data fetching](/v2/solid-start/building-your-application/data-fetching) or [Data mutation](/v2/solid-start/building-your-application/data-mutation) before introducing a separate API boundary.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Data fetching
use_cases: >-
api calls, database queries, loading states, preloading data, server-side
fetching, route data
tags:
- fetch
- data
- query
- async
- server
version: "2.0"
description: >-
Fetch data in SolidStart v2 with Solid Router queries, createAsync, and
server-backed functions compiled from the use server directive.
---

Data loading is built around Solid Router's [`query`](/solid-router/reference/data-apis/query) API and [`createAsync`](/solid-router/reference/data-apis/create-async).
The `"use server"` directive lets a query body run only on the server when needed.

## Basic query usage

Use `query` to define cached data loading and `createAsync` to read the result inside a route component.

```tsx title="src/routes/posts.tsx"
import { For } from "solid-js";
import { createAsync, query } from "@solidjs/router";

const getPosts = query(async () => {
const response = await fetch("https://example.com/api/posts");
return response.json() as Promise<Array<{ id: number; title: string }>>;
}, "posts");

export default function PostsPage() {
const posts = createAsync(() => getPosts());

return <For each={posts()}>{(post) => <li>{post.title}</li>}</For>;
}
```

## Keep the data function on the server

If your query needs direct access to server-only resources, add the `"use server"` directive inside the query function.

```tsx title="src/routes/account.tsx"
import { createAsync, query } from "@solidjs/router";
import { useSession } from "@solidjs/start/http";

const getCurrentUser = query(async () => {
"use server";

const session = await useSession<{ userId?: string }>({
password: process.env.SESSION_SECRET as string,
name: "session",
});

return { userId: session.data.userId ?? null };
}, "currentUser");

export default function AccountPage() {
const user = createAsync(() => getCurrentUser());
return <pre>{JSON.stringify(user(), null, 2)}</pre>;
}
```

## Preload route data

If you want to warm the query before rendering the page, export a `route.preload` function from the route module.

```tsx title="src/routes/posts/[id].tsx"
import { createAsync, query, type RouteDefinition } from "@solidjs/router";

const getPost = query(async (id: string) => {
"use server";
const response = await fetch(`https://example.com/api/posts/${id}`);
return response.json();
}, "post");

export const route = {
preload: ({ params }) => getPost(params.id),
} satisfies RouteDefinition;

export default function PostPage(props: { params: { id: string } }) {
const post = createAsync(() => getPost(props.params.id));
return <pre>{JSON.stringify(post(), null, 2)}</pre>;
}
```

Cache invalidation and advanced query behavior are handled by [Solid Router](/solid-router), so use the Solid Router references when you need lower-level cache semantics.
Loading
Loading