7

I am trying to fetch User from my own API which needs a token (i can store the token in localStorage or in Cookies). As there is no localStorage access when using server side rendering, i have to use cookies. But the cookie is undefined in the server. I tried several NPM packages.

I just want to fetch the user from Api with user token and all this in SSR.

this the code i am trying to work with.

import axios from "axios";
import React from "react";
import { URLs } from "../../../app.config";

const getUser = async () => {
  axios.defaults.withCredentials = true;
  axios.defaults.baseURL = URLs.backend;

  const token = ""; // * i need that token here
  axios.defaults.headers.common["Authorization"] = "Bearer " + token;

  try {
    return await (
      await axios.get("/user/user")
    ).data.user;
  } catch (err: any) {
    console.log(token);
    console.log(err.response.data);
    return null;
  }
};

export default async function Login() {
  const user = await getUser();

  if (!user) return <div className="text-red-500">No user found</div>;

  return <div>Logged in User:{JSON.stringify(user)}</div>;
}

this is my dependencies

 "dependencies": {
    "@types/node": "18.11.9",
    "@types/react": "18.0.25",
    "@types/react-dom": "18.0.8",
    "axios": "^1.1.3",
    "cookies-next": "^2.1.1",
    "eslint": "8.27.0",
    "eslint-config-next": "13.0.3",
    "framer-motion": "^7.6.6",
    "next": "13.0.3",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-icons": "^4.6.0",
    "react-loader-spinner": "^5.3.4",
    "socket.io-client": "^4.5.3",
    "sweetalert2": "^11.6.8",
    "swr": "^1.3.0",
    "typescript": "4.8.4"
  },

I tried npm packages

react-cookie
cookies-next

Or is there any other way to get the cookie from users browser and use SSR? I found solutions of Next Js 12 but in version 13 there is no _app.js file or getServerSideProps functions. I want to get cookies with Next Js 13 App folder structure.

Mir Tanvir Ahmed
  • 109
  • 1
  • 1
  • 7
  • 2
    I was struggling with something similar trying to use Next.js 13. I settled with their middleware https://nextjs.org/docs/advanced-features/middleware. Essentially page requests you can have custom logic and the ability to get/set headers server side. Then on your server component, you can import next/headers and get those cookies. The only caveat with this however is that these cookies cannot be accessed on a client component it seems. I am still trying to figure out a way to have some sort of persistent state via cookies between server and client components. – NacDan Nov 16 '22 at 23:29
  • you need to use client instead of server component – Firdaus Ismail Nov 16 '22 at 23:32
  • @FirdausIsmail Not necessarily, look at my above comment. I have been able to get cookies server side using middleware. – NacDan Nov 16 '22 at 23:33

1 Answers1

13

You can fetch cookies in Nextjs 13 from next/headers server side.

Example:

import axios from "axios";
import React from "react";
import { cookies } from 'next/headers'; // Import cookies

const getUser = async () => {

  const nextCookies = cookies(); // Get cookies object

  const token = nextCookies.get('token') // Find cookie

  if(!token) {
    throw new Error("Missing token")
  }

  try {
    const response = await axios.get("/user", {
      headers: {
        // NOTE: If using NextJS < 13.4.0 use:
        // authorization: `bearer ${token}` // Use your cookie
        authorization: `bearer ${token.value}` // Use your cookie
      }
    })

    return response.data.user;

   } catch (err: any) {
     console.log(token);
     console.log(err.response.data);
     return null;
   }
};

export default async function Login() {

  const user = await getUser();

  if (!user) return <div className="text-red-500">No user found</div>;

  return <div>Logged in User:{JSON.stringify(user)}</div>;
}
Nicolai Lissau
  • 7,298
  • 5
  • 43
  • 57
  • 2
    I would recommend using fetch, instead of axios, due to the built-in support for caching/revalidating fetch responses. Axios is no longer needed. – leerob Jan 27 '23 at 14:51
  • 2
    yes but you can not access server only cookies, if you want to fire an api call in this page, you need a 'use client' in front of the file as well, which can. not use together with next/headers. – crazy_phage Mar 18 '23 at 14:54
  • I had to use `nextCookies.get('token')?.value` to get the token value. Otherwise I've got an object like `{ name: 'token', value: '...' }` – gazdagergo Jul 06 '23 at 06:48
  • That is odd. The documentation is clear https://nextjs.org/docs/app/api-reference/functions/cookies#cookiesgetname – Nicolai Lissau Jul 06 '23 at 17:28
  • Just tried in Next 13.4.0 and you are correct. My example is using Next 13.0.0. Updated the answer. – Nicolai Lissau Jul 07 '23 at 08:18
  • See this package: https://github.com/moshest/next-client-cookies – Moshe Simantov Aug 03 '23 at 12:12