A guide to cookies in Next.js

mangelosanto

Matt Angelosanto

Posted on April 13, 2023

A guide to cookies in Next.js

Written by Georgey V B✏️

Cookies are data blobs that our browsers unknowingly contain. While some are fervent invaders of privacy, others attempt to improve the browsing experience by keeping track of your browsing habits, preferences, and more. Cookies are useful in situations like authentication, improving the UX, quicker response times, and the list goes on.

In this article, we'll explore two packages that will allow us to achieve setting cookies in a Next.js application and implement them into an actual use case. To follow along, head over to this GitHub repository. Let's get started!

Jump ahead:

Cookies: Boon or ban?

Cookies are little text files that websites place on users' computers. Cookies have generated discussion in recent years and have both benefits and drawbacks. Cookies can remember user preferences and settings, which can improve your session and personalization of surfing for users. The ability of cookies to trace users' online behavior, however, presents privacy issues. As a result, several websites have standards requiring them to display their biscuit usage and provide users with the option to opt-out.

Furthermore, a few browsers give users the choice to remove or delete cookies, which may assist in guarding their privacy. Cookies can be helpful for users and websites, but it's important to abide by the rules and be aware of any privacy dangers. Users are becoming more cautious and switching to different browsers to help them track cookies and disable adverts. It is ultimately up to users and website administrators to use cookies wisely because they can be beneficial and adverse.

Working with react-cookies in Next.js

The first package we will explore is react-cookies. This package aims to help you load and save cookies within your React application. Let's create a simple application that keeps track of registered users.

If you haven't already, launch a Next.js application by typing the following command:



npx create-next-app --ts


Enter fullscreen mode Exit fullscreen mode

With that done, install react-cookie with the following code:



npm install react-cookie


Enter fullscreen mode Exit fullscreen mode

To start using the Hooks, add the CookiesProvider component in the _app.tsx file, like so:



import type { AppProps } from 'next/app';
import { CookiesProvider } from 'react-cookie';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <CookiesProvider>
      <Component {...pageProps} />
    </CookiesProvider>
  );
}

export default MyApp;


Enter fullscreen mode Exit fullscreen mode

With this done, the Hooks are now available from any part of your application. Start using it by importing the useCookies Hook, as shown below:



import { useCookies } from 'react-cookie';


Enter fullscreen mode Exit fullscreen mode

We can now fetch, add, and remove cookies from the application. Let's start off by adding a useEffect Hook to fetch all cookies on load:



import { useCookies } from 'react-cookie';

const [cookies, setCookie, removeCookie] = useCookies(['user']);
const Home: NextPage = () => {
  useEffect(() => {
    console.log('Cookies: ', cookies);
  }, [cookies]);

  return (
  <div>...</div>
)}


Enter fullscreen mode Exit fullscreen mode

For now, you shouldn't be able to see any cookies. So, let's create a function to set cookies using the setCookie() function:



import { useRouter } from 'next/router'

//...inside the defualt function
const router = useRouter();

const setCookieHandler = () => {
  setCookie('new-user', true, {
    path: '/',
  });

  router.replace("/");
};


Enter fullscreen mode Exit fullscreen mode

The setCookie() function takes in three arguments: the key, the key-value, and some configuration choices. These choices include, MaxAge, Path, Domain, expires, etc. The path option was used in this case to allow the program to access the cookie from any location.

As you can see, we also used the useRouter() Hook to reload our page using the replace() method to avoid adding a URL entry into the history stack. It will just look like the page re-rendered!

As we move forward, remember that this tutorial is focused only on demonstrating the capabilities of the specific packages. Therefore, we will assume that you understand concepts like authentication flow. To learn more about authentication in Next.js, refer to this guide. You can also review authentication flows in this article.

Binding a function to a button

Next up, let's bind this function to a button. Input the following code:



{!cookies['user'] && (
  <button onClick={setCookieHandler} className={styles.button}>
    Complete new user registration!
  </button>
)}


Enter fullscreen mode Exit fullscreen mode

In this case, the button will only render if the cookie exists. Go ahead and run the development server to see this in action. You can see this cookie visually using the dev tools by triggering Control+Shift+J and then selecting the Application section, as shown below: Getting Started With Next.js and Cookies

With that done, let's remove the cookie to allow the user to sign out. First, write another function:



const removeCookieHandler = () => {
  removeCookie('new-user');

  router.replace("/");
};


Enter fullscreen mode Exit fullscreen mode

Now, bind it to another button that will only render if the cookie is available. What does that mean? The cookie will be available if the user is registered. Here's what that will look like:



{cookies['new-user'] && (
  <button onClick={removeCookieHandler} className={styles.resetbutton}>
    Reset new user registration
  </button>
)}


Enter fullscreen mode Exit fullscreen mode

Getting Started With Next.js and Cookies Part Two

With that done, let's explore the second package, cookies-next.

Using the cookies-next package in Next.js

Moving forward, we will look at how to use the cookies-next package. This package fits more with the Next.js ecosystem because it can be used anywhere on the client side, on the server side through getServerSideProps, and even with Next.js API routes. Here are the two packages head-to-head: Comparing Next.js Cookie Packages

Another surprising fact about cookies-next (this one's for all the bundle-phobic developers) is that it's almost half the size of react-cookie. Essentially, making it more desirable to use it in your next project!🎉

As tradition goes, let's start off by installing cookies-next with the following command:



npm install cookies-next 


Enter fullscreen mode Exit fullscreen mode

The cookies-next package comes inbuilt with similar functions to the react-cookies package. These functions can be used for setting and removing cookies. Let's create handler functions for setting and removing cookies with the following code:



// adding cookies
const addCookie = () => {
  setCookie('user', true, {
    path: '/',
  });
  router.replace('/');
};

// removing cookies
const removeCookie = () => {
  deleteCookie('user', {
    path: '/',
  });
  router.replace('/');
};


Enter fullscreen mode Exit fullscreen mode

With that done, you can go ahead and test it out by binding it to different buttons that render if the cookie exists. In addition to getServerSideProps and API routes, cookies-next can also be used on the server side of the application. Let's look at an example where the user receives some information, has it verified, and then sets a cookie to indicate the information's legitimacy, all on an API route.

Implementing API routes

Go ahead and make a new API route inside ./pages/api/verify-otp.ts. Inside the file, create a basic handler function with the following code:



export default function handler (
  req: NextApiRequest,
  res: NextApiResponse
) {
  return;  
}


Enter fullscreen mode Exit fullscreen mode

The cookie will be set to indicate the trustworthiness of the user and expire after a specific period. More specifically, it will expire if there is some type of verification, such as a database to check the credentials or some OTP logic. The handler function is as follows:



if (
    req.method === 'POST' // only allow POST requests
  ) {
  // caputure the credentials required for verification from the request body
  const { name } = req.body;

  //   otp verification logic

  //   set cookie
  setCookie('authorize', true, {
    req,
    res,
    maxAge: 60 * 60 * 24 * 7, // 1 week
    path: '/',
  });

  //   respond with status and message
  return res.status(200).json({
    message: `${name} is authorized to access`,
    authorize: true,
    code: '20-0101-2092',
  });
}


Enter fullscreen mode Exit fullscreen mode

Here, the cookie expires after a week and will require the user to re-verify again. On successful verification, the API responds with a status 200 message with relevant data that can be displayed in the frontend.

Accessing API routes from the frontend

Now, let's try to access this route from the frontend. The function can be triggered only if the user is registered the first time. Create a function with the following code:



const verifyOTP = async (name: string) => {
  const response = await fetch('/api/verify-otp', {
    method: 'POST',
    body: JSON.stringify({ name }),
  });

  const data = await response.json();

  if (data.authorize) {
    setAuthorization(true);
    setLaunchCode(data.code);
  } else {
    setAuthorization(false);
    alert('Invalid OTP');
  }
};


Enter fullscreen mode Exit fullscreen mode

We can use the useState Hook to store the data coming from the API route and render the button conditionally and based on the isAuthorized variable. Use the following code:



const [isAuthorized, setAuthorization] = useState(false);
const [launchCode, setLaunchCode] = useState('');


Enter fullscreen mode Exit fullscreen mode

With this done, go ahead and try out the code written so far. You can check if the cookie exists by opening up the dev tools and heading selecting the Application section, as shown below: Accessing Next.js Dev Tools and Cookies

I attempted to make the example more entertaining by generating a random code at every login. It will also set a cookie on the API route. You can experiment with your own original ideas and try out something cooler! Here's what my example looks like: Final Product of Creating Cookies in Next.js

Conclusion

Cookies are crucial to web development. The react-cookie and cookies-next packages are ideal for various use cases because of their distinctive features and advantages. React-cookie is far more popular, providing simple-to-use APIs and great compatibility with React framework. In contrast, cookies-next, a relatively new package explicitly created for Next.js, offers server-side rendering capabilities and improved security measures.

No matter which package you select, it is essential to understand how cookies operate and how to use them safely to prevent any security issues. These two packages make it simple for developers to handle cookies in Next.js applications, making it simpler to customize UX and enhance website speed.


LogRocket: Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket signup

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — start monitoring for free.

💖 💪 🙅 🚩
mangelosanto
Matt Angelosanto

Posted on April 13, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related