Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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