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
      Common Questions

      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.

      Common Questions


      
      When writing APIs, you may face challenges such as retrieving URL parameters, reading cookies, and managing different methods. Here, we offer an overview of these challenges for your reference during actual development.

      How to Get URL Parameters?


      
      // app/api/search/route.ts
      // Access /api/search?query=hello
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      const searchParams = request.nextUrl.searchParams;
      const query = searchParams.get('query'); // query
      }
      

      How to Handle Cookies?


      
      Method 1: Using the NextRequest Object
      // app/api/route.ts
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      export async function GET(request) {
      const token = request.cookies.get('token')
      request.cookies.set(`token2`, 123)
      }
      Here, request is a NextRequest object. Compared to Request, NextRequest provides more convenient methods. However, setting a cookie this way only modifies the request's cookies, not the response's cookies.
      
      Method 2: Using the cookies Method from next/headers
      Since the cookies instance is read-only, to set a cookie, you need to return a Response instance with the Set-Cookie header.
      // app/api/route.ts
      import { cookies } from 'next/headers';
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      const cookieStore = cookies();
      const token = cookieStore.get('token');
      return new Response('Hello, Next.js!', {
      status: 200,
      headers: { 'Set-Cookie': `token=${token}` },
      });
      }
      

      How to Handle Headers?


      
      Method 1: Using the NextRequest Object
      // app/api/route.ts
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      const headersList = new Headers(request.headers);
      const referer = headersList.get('referer');
      }
      
      Method 2: Using the headers Method from next/headers
      Since the headers instance is read-only, to set headers, you need to return a Response instance with the new headers.
      // app/api/route.ts
      import { headers } from 'next/headers';
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      const headersList = headers();
      const referer = headersList.get('referer');
      return new Response('Hello, Next.js!', {
      status: 200,
      headers: { referer: referer },
      });
      }
      

      How to Redirect?


      
      Use the redirect method from next/navigation.
      import { redirect } from 'next/navigation';
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      redirect('https://nextjs.org/');
      }

      How to Get the Request Body?


      
      // app/items/route.ts
      import { type NextRequest } from 'next/server'; import { NextResponse } from 'next/server';
      export async function POST(request: NextRequest) {
      const res = await request.json();
      return NextResponse.json({ res });
      }
      If the request body is of FormData type:
      // app/items/route.ts
      import { type NextRequest } from 'next/server'; import { NextResponse } from 'next/server';
      export async function POST(request: NextRequest) {
      const formData = await request.formData();
      const name = formData.get('name');
      const email = formData.get('email');
      return NextResponse.json({ name, email });
      }
      

      How to Set CORS?


      
      // app/api/route.ts
      import { type NextRequest } from 'next/server';
      
      export function GET(request: NextRequest) {
      return new Response('Hello, Next.js!', {
      status: 200,
      headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      },
      });
      }
      

      How to Respond with Non-UI Content?


      
      You can return content without a UI. In this example, visiting /rss.xml returns XML content:
      // app/rss.xml/route.ts
      export async function GET() {
      return new Response(`<?xml version="1.0" encoding="UTF-8" ?>
      <rss version="2.0">
      <channel>
      <title>Next.js Documentation</title>
      <link>https://nextjs.org/docs</link>
      <description>The React Framework for the Web</description>
      </channel>
      </rss>`);
      }
      Note: Special files like sitemap.xml, robots.txt, app icons, and open graph images are supported by Next.js and will be discussed in detail in the Metadata section.
      

      Streaming


      
      The typing effect in OpenAI is achieved using streaming:
      // app/api/chat/route.ts
      import OpenAI from 'openai';
      import { OpenAIStream, StreamingTextResponse } from 'ai';
      import { type NextRequest } from 'next/server';
      const openai = new OpenAI({
      apiKey: process.env.OPENAI_API_KEY,
      });
      export const runtime = 'edge';
      export async function POST(req: NextRequest) {
      const { messages } = await req.json();
      const response = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      stream: true,
      messages,
      });
      const stream = OpenAIStream(response);
      return new StreamingTextResponse(stream);
      }
      You can also use the Web API directly to implement streaming:
      // app/api/route.ts
      // https://developer.mozilla.org/docs/Web/API/ReadableStream#convert_async_iterator_to_stream
      function iteratorToStream(iterator: AsyncIterator<Uint8Array>): ReadableStream {
      return new ReadableStream({
      async pull(controller) {
      const { value, done } = await iterator.next();
      
      if (done) {
      controller.close();
      } else {
      controller.enqueue(value);
      }
      },
      });
      }
      function sleep(time: number): Promise<void> {
      return new Promise((resolve) => {
      setTimeout(resolve, time);
      });
      }
      const encoder = new TextEncoder();
      async function* makeIterator() {
      yield encoder.encode('<p>One</p>');
      await sleep(200);
      yield encoder.encode('<p>Two</p>');
      await sleep(200);
      yield encoder.encode('<p>Three</p>');
      }
      export async function GET() {
      const iterator = makeIterator();
      const stream = iteratorToStream(iterator);
      return new Response(stream);
      }
      Note: For more comprehensive examples and explanations of streaming, refer to "How to Implement a Streaming API in Next.js v14?"
      

      Summary


      
      Congratulations on completing this section! 👏👏
      In this section, we introduced how to define a route handler using the new convention file route.js. Remember that route.js cannot coexist with page.js at the same level.
      We also covered common issues when writing route handlers. Whenever possible, use NextRequest and NextResponse, as they are extensions of the native Request and Response, offering convenient methods for handling URLs and cookies.