Cookies are small pieces of data that are stored by the browser and sent to the server with every request. They are often used to store user preferences, authentication tokens, session data, and other information. In Next.js 14, you can use the cookies()
function from the next/headers
module to access and manipulate cookies in your server components, route handlers, middleware, and server actions.
To set a cookie, you need to use the cookies().set()
method, which takes a cookie name, value, and options as arguments. The options can include properties such as maxAge
, httpOnly
, secure
, sameSite
, etc. You can only set cookies in a Server Action or Route Handler, because HTTP does not allow setting cookies after streaming starts.
To read a cookie, you need to use the cookies().get()
 method, which takes a cookie name as an argument and returns an object with the name and value of the cookie. If the cookie is not found, it returns undefined
. If multiple cookies match the name, it returns only the first one.
To delete a cookie, you can use the cookies().delete()
method, which takes a cookie name as an argument and removes the cookie from the response. Alternatively, you can set a new cookie with the same name and an empty value, or set the maxAge
or expires
option to a value in the past.
Example: Managing Cookies in a Route Handler
Here is a complete example (with explanations in the comments) of how to set, read, and delete a cookie named jwt
 in a Route Handler:
// app/api/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
export async function POST(request: NextRequest) {
// set a cookie named jwt with a value and some options
cookies().set('jwt', 'some-token', {
maxAge: 60 * 60 * 24, // one day in seconds
httpOnly: true, // prevent client-side access
sameSite: 'strict', // prevent cross-site requests
});
// read the cookie named jwt and log its value
const jwt = cookies().get('jwt')?.value;
console.log(jwt); // some-token
// delete the cookie named jwt
cookies().delete('jwt');
// return a JSON response
return Response.json({ message: 'Cookie demo' });
}
To test the code above, you can use a tool like Postman or curl to send a POST request to the /api
 route. For example, using curl, you can run the following command in a terminal:
curl -X POST http://localhost:3000/api
You should see the following output in the terminal:
{"message":"Cookie demo"}
You should also see the following output in the console where you run the Next.js app:
some-token
Using Cookies in Middleware
Using cookies in middleware in Next.js 14 is similar to using cookies in Route Handlers or Server Actions. You can use the cookies
object from the next/headers
module to access and manipulate cookies in your middleware. You can use the cookies().set()
, cookies().get()
, and cookies().delete()
methods to set, read, and delete cookies respectively. You can also pass options such as maxAge
, httpOnly
, secure
, sameSite
, etc. to customize your cookies.
Below is an example that demonstrates how to use cookies in middleware:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest) {
// get the cookie named name
const name = cookies().get('name')?.value;
// if the cookie is not set, set it to a default value
if (!name) {
cookies().set('name', 'Guest', {
maxAge: 60 * 60 * 24, // one day in seconds
httpOnly: true, // prevent client-side access
sameSite: 'strict', // prevent cross-site requests
});
}
// return the next response
return NextResponse.next();
}
Server Actions and Cookies
Recent versions of Next.js introduced the concept of Server Actions. These are functions that you can export from your components and are triggered by an action, such as submitting a form.
import { cookies } from "next/headers";
export default function Message() {
async function markAsSeen() {
"use server";
cookies().set("viewedWelcomeMessage", "true");
}
const viewedWelcomeMessage = cookies().has("viewedWelcomeMessage");
if (viewedWelcomeMessage) {
return <div>Welcome back!</div>;
}
return (
<form action={markAsSeen}>
Welcome! <button type="submit">Mark as seen</button>
</form>
);
}
Managing Cookies with Pages Router (Legacy)
This section is for developers who prefer to use the old-fashioned /pages
directory. Here you have the getServerSideProps
function, which is executed server-side before rendering the page. It allows you to both get and set HttpOnly cookies. Here’s a sample code snippet to illustrate this:
import { GetServerSideProps } from "next";
export const getServerSideProps: GetServerSideProps = async (context) => {
const viewedWelcomeMessage = context.req.cookies.viewedWelcomeMessage;
if (viewedWelcomeMessage === "true") {
return { props: { message: "Welcome back!" } };
}
context.res.setHeader("Set-Cookie", "viewedWelcomeMessage=true");
return { props: { message: "Welcome!" } };
};
See also:
- Next.js: Using getServerSideProps() with TypeScript
- Next.js getServerSideProps(): Tutorial & Example
Working with Cookies in API Routes (Legacy)
Setting cookies within API Routes (in the /pages
directory) in Next.js is simple and intuitive. Here’s how you can set a cookie within an API Route:
import { NextApiRequest, NextApiResponse } from "next";
import cookie from "cookie";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<{ message: string }>
) {
const viewedWelcomeMessage = req.cookies.viewedWelcomeMessage;
if (viewedWelcomeMessage === "true") {
return res.status(200).json({ message: "Welcome back!" });
}
res.setHeader("Set-Cookie", cookie.serialize("viewedWelcomeMessage", "true"));
return res.status(200).json({ message: "Welcome!" });
}
Client-Side Cookies in Next.js 14
While we’ve focused primarily on server-side cookies, Next.js also supports client-side cookies. Libraries such as react-cookie
or universal-cookie
can provide a user-friendly experience.
const [cookies, setCookie] = useCookies(["name"]);
Best Practices
While managing cookies in Next.js 14, adhere to the following best practices:
- Always use HttpOnly cookies for sensitive data to mitigate the risk of XSS attacks.
- Use
localStorage
for storing non-sensitive information. - Regularly delete cookies that have served their purpose.
Potential Pitfalls
Despite the ease of managing cookies in Next.js 14, there are potential pitfalls to be aware of:
- Modifying the request in middleware doesn’t impact the request anywhere else.
- Setting multiple cookies requires an array of cookie strings to prevent overwriting.
Conclusion
You’ve learned how to set, read, and delete cookies in Next.js 14 (either you use the new /app
directory or the old /pages
directory). I hope the instructions and code examples in the article can help you in some way. Happy coding & have a nice day. See you again in other tutorials on Sling Academy!