Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      Route handlers

      Next.js Mastery: From Fundamentals to Full-Stack

      Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.

      Route Handlers


      
      In Next.js, route handlers play a crucial role in defining custom logic for handling routes using the Web Request and Response API. These route handlers act as the bridge between the client and server, facilitating their interaction through API endpoints.

      Defining a Route Handler


      
      To get started, you need to create a file named route.ts (note the singular form: "route," not "router"). This file should be placed within the app directory and can be nested in subdirectories under app. However, keep in mind that page.tsx and route.tscannot reside at the same level because both respond to routes: page.tsx manages UI rendering, while route.ts handles requests. Having both at the same level would confuse Next.js about which one to prioritize.

      GET Request

      Let's begin with setting up a GET request, like fetching a list of articles. Create the file app/api/blogs/route.ts and add the following code:
      import { NextResponse } from 'next/server';
      
      interface Post {
      userId: number;
      id: number;
      title: string;
      body: string;
      }
      
      export async function GET() {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts');
      const data: Post[] = await res.json();
      
      return new NextResponse(JSON.stringify(data));
      }
      To see the returned data, visit http://localhost:3000/api/blogs in your browser.
      
      Playground:
      
      In this example:
      • We export an async function named GET to handle the GET request. Note the use of export rather than export default.
      • We utilize the NextResponse object from next/server to structure the response content. Alternatively, you can use the standard Response object:
      export async function GET() {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts');
      const data: Post[] = await res.json();
      
      return new Response(JSON.stringify(data));
      }
      Using NextResponse is generally recommended as it offers TypeScript-friendly features and conveniences like cookie handling, being a wrapper around the standard Response.
      
      Organizing the endpoint under the app/api folder is for clarity—it helps differentiate between API endpoints and pages. However, placing it in app/blogs/route.ts would work too, with the endpoint being /blogs.
      

      Supported Methods

      Next.js supports various HTTP methods such as GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. Unsupported methods automatically return a 405 Method Not Allowed response.
      
      Here's an example:
      export async function GET(request) {}
      export async function HEAD(request) {}
      export async function POST(request) {}
      export async function PUT(request) {}
      export async function DELETE(request) {}
      export async function PATCH(request) {}
      export async function OPTIONS(request) {}
      

      POST Request

      Let's create a POST request. Update app/api/blogs/route.js with:
      export async function POST(request: Request) {
      const article = await request.json()
      
      return NextResponse.json({
      id: Math.random().toString(36).slice(-8),
      data: article
      }, { status: 201 })
      }
      
      Let's call this endpoint http://localhost:3000/api/blogs with Postman:
      
      Note: Make sure your application is running on 3000 port
      

      Parameters

      Each request handler can take two optional parameters: request and context.
      export async function GET(request, context) {}
      
      • Request Object
      The request object, an extension of the Web Request API, is a NextRequest object that allows easy access to cookies and URL handling.
      For example:
      export async function GET(request, context) {
      // When accessing /home, the value of pathname is /home
      const pathname = request.nextUrl.pathname
      // When accessing /home?name=lee, the value of searchParams is { 'name': 'lee' }
      const searchParams = request.nextUrl.searchParams
      }
      
      • Context Object
      Currently, context contains only params, which holds dynamic route parameters:
      // app/dashboard/[team]/route.js
      export async function GET(request, { params }) {
      const team = params.team
      }
      When accessing /dashboard/1, params is { team: '1' }.
      

      Example Scenarios

      Here are some examples of how parameters work:
      Example
      URL
      params
      app/dashboard/[team]/route.js
      /dashboard/1
      { team: '1' }
      app/shop/[tag]/[item]/route.js
      /shop/1/2
      { tag: '1', item: '2' }
      app/blog/[...slug]/route.js
      /blog/1/2
      { slug: ['1', '2'] }
      

      Review

      To consolidate these concepts, let's modify our GET request to return specific data fields.
      The requirement is that currently, when sending a GET request to /api/blogs, all blog data is returned. Now, we want the GET request to /api/posts/1?dataField=title to specifically retrieve the article data for blog id with 1, with dataField indicating which fields of data should be returned.
      
      Let's begin by creating a new file named /api/blogs/[blogId]/route.ts with the following code:
      export async function GET(
      request: NextRequest,
      { params }: { params: { blogId: string } }
      ) {
      const blogId = params.blogId;
      
      // Check if the request contains a "dataField" search parameter
      const dataField = request.nextUrl.searchParams.get('dataField');
      
      const res = await fetch(
      `https://jsonplaceholder.typicode.com/posts/${blogId}`
      );
      const data: Post = await res.json();
      
      // If "dataField" is present, return only that specific field
      if (dataField) {
      const result = { [dataField]: data[dataField as keyof Post] };
      return new NextResponse(JSON.stringify(result), {
      headers: { 'Content-Type': 'application/json' },
      });
      }
      
      // Otherwise, return the entire data
      return new NextResponse(JSON.stringify(data), {
      headers: { 'Content-Type': 'application/json' },
      });
      }
      
      Using Postman, if you request http://localhost:3000/api/posts/1?dataField=title, you'll get the title of the post with id 1. If you just request http://localhost:3000/api/posts/1, you'll receive the entire post data.
      
      
      This guide should help you understand how to define and manage route handlers in Next.js. If you need further examples or clarification, feel free to ask!