How Route Handlers and API Routes work
On the App Router, a Route Handler is defined in a route.js or route.ts file inside the app directory. A route.js file cannot sit in the same route segment as a page.js file, which is why handlers usually live under a folder such as app/api. A route file exports one function per HTTP method; the supported methods are GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS. Calling a method the route file does not export returns 405 Method Not Allowed.
The request argument is a
NextRequest, an extension of the Web Request API that adds cookie access and a parsednextUrlobject.Since Next.js 15, the
context.paramsargument is a Promise and must be awaited; a codemod handles the migration.A route is the lowest-level routing primitive and takes no part in layouts or client-side navigation.
An API Route handler receives Node.js objects, with req as an http.IncomingMessage and res as an http.ServerResponse that has helpers such as res.status and res.json. API Routes set no CORS headers, so by default they only accept same-origin requests.
Both conventions keep pages and API endpoints in one codebase (see the benefits of Next.js). For request code that runs in front of routes, see Next.js middleware and when to use it.
Caching, security and static export
Caching. Without Cache Components, Route Handlers are not cached by default; only GET handlers can opt in, for example with export const dynamic = 'force-static'. Next.js 15 changed the default for GET Route Handlers from static to dynamic; before 15, GET handlers were cached by default. With Cache Components enabled (Next.js 16), GET Route Handlers follow the same model as UI routes. They run at request time by default and can be prerendered.
Security. Route Handlers are public HTTP endpoints that any client can call, so each handler needs its own authentication and authorization.
Static export. API Routes cannot be used with static exports. With output: 'export', only GET Route Handlers work, and only with the dynamic segment config set to 'force-static'. The Route Handlers documentation covers each option. For an API layer built into a Next.js app, see Next.js development.
Sources
- Route HandlersNext.js · nextjs.org
- API RoutesNext.js · nextjs.org
- route.jsNext.js · nextjs.org
- Backend for FrontendNext.js · nextjs.org