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=helloimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsexport 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 likesitemap.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.tsimport 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_streamfunction 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.