Skip to content
rest-rpc
Esc
navigateopen⌘Jpreview
On this page

Next.js

Register contract routes in Next.js App Router route handlers.

Use @rest-rpc/next to create route handlers for Next.js App Router.

Install

pnpm add @rest-rpc/core @rest-rpc/next

Single Route Handler

Contract path: /api/todos/:id App router route: app/api/todos/[id]/route.ts

import { createRouteHandler } from "@rest-rpc/next";
import { api } from "@/contract";

export const { GET } = createRouteHandler(api.todos.get, ({ id, context }) => {
	const userAgent = context.request.headers.get("user-agent");
	void userAgent;

	const todo = todos.get(id);

	if (!todo) {
		return {
			status: 404,
			body: {
				code: "TODO_NOT_FOUND",
			},
		};
	}

	return todo;
});

Handlers receive flattened request input where context.request contains the native Request.

get({ id, context }) {
	return loadTodo({
		id,
		authorization: context.request.headers.get("authorization"),
	});
}

Catch-all Routes

Contract path: /api/* App router route: app/api/[...rest]/route.ts

import { createRouterHandler } from "@rest-rpc/next";
import { api } from "@/contract";

export const { GET, POST } = createRouterHandler(api, {
	todos: {
		list: async ({ context }) => {
			const userAgent = context.request.headers.get("user-agent");
			void userAgent;

			return todos.list();
		},
		create: async ({ title }) => {
			const todo = await todos.create({ title });

			return {
				status: 201,
				body: todo,
			};
		},
	},
});

With a catch-all route, @rest-rpc/next owns path matching inside that route module. Requests that do not match the contract return 404.

Next route handlers use module exports such as runtime, dynamic, and revalidate to define route-level behavior. With a catch-all route, those settings apply to every contract route mounted under that file.

Error Handling

Use errorHandlers to customize server-generated error responses. Declared responses returned from handlers, including ContractResponseError, do not run through these hooks.

export const { GET, POST } = createRouterHandler(api, handlers, {
	errorHandlers: {
		onRequestValidationError: ({ issues }) => ({
			status: 422,
			body: { code: "VALIDATION_ERROR", issues },
		}),
		onUnhandledError: () => ({
			status: 500,
			body: { code: "INTERNAL_SERVER_ERROR" },
		}),
	},
});

WebSocket Support

Websocket routes are not supported in Next.js route handlers because Next does not itself support WebSocket connections. If you need WebSocket support, use a different server adapter that supports WebSockets.

Was this page helpful?