How to use cookie inside `getServerSideProps` method in Next.js? - javascript

I have to send current language on endpoint. But getting language from Cookie returns undefined inside getServerSideProps.
export async function getServerSideProps(context) {
const lang = await Cookie.get('next-i18next')
const res = await fetch(`endpoint/${lang}`)
const data = await res.json()
return {
props: { data },
}
}
export default Index;
What is the proper way to get cookie inside getServerSideProps?

You can get the cookies from the req.headers inside getServerSideProps:
export async function getServerSideProps(context) {
const cookies = context.req.headers.cookie;
return {
props: {},
};
}
You could then use the cookie npm package to parse them:
import * as cookie from 'cookie'
export async function getServerSideProps(context) {
const parsedCookies = cookie.parse(context.req.headers.cookie);
return { props: {} }
}

To avoid having to parse the cookies string from context.req.headers.cookie, Next.js also provides the cookies as an object which can be accessed with context.req.cookies.
export async function getServerSideProps(context) {
const lang = context.req.cookies['next-i18next']
// ...
}
From getServerSideProps documentation:
The req in the context passed to getServerSideProps provides built in
middleware that parses the incoming request (req). That middleware is:
req.cookies - An object containing the cookies sent by the request.
Defaults to {}

You can use parseCookies function with cookie package
import cookie from "cookie"
function parseCookies(req){
return cookie.parse(req ? req.headers.cookie || "" : document.cookie);
}
And then get access like that.
export async function getServerSideProps({ req} ) {
const cookies = parseCookies(req);
// And then get element from cookie by name
return {
props: {
jwt: cookies.jwt,
}
}
}

If you are using Axios this is very simple
This will work inside getServerSideProps method. You can't get access to the cookie by using withCredentials because this is on the server.
const { token } = context.req.cookies;
const response = await axios.get('/staff/single', {
headers: { Cookie: `token=${token};` },
});
or try (This will work on the client)
const response = await axios.get('/staff/single', {
headers: { withCredentials: true },
});

how are you doing?
you can use Something like this :
export async function getServerSideProps(context) {
console.log(context.req.cookies)
}
so easy and so beautifuly!

Related

Cannot Get Prop Of NextRequest

I'm trying to MiddleWare With Next.js's Middleware and JWT.
When I console.log cookies and typeof cookies variable im getting on console:
{
token: 'token='myToken'; Path=/'
}
object
Here is my code:
import { NextRequest, NextResponse } from "next/server";
import { verify } from "jsonwebtoken";
const SECRET = process.env.SECRET;
export function middleware(req, res) {
const cookies = req.cookies;
const url = req.url;
if (url.includes("/admin")) {
console.log(cookies)
console.log(typeof cookies)
}
return NextResponse.next();
}
But when i try to get token prop like cookies.token, i got undefined
Any idea of what's going on?
Funny Answer:
I just need to use get method for get specified prop
const cookies = req.cookies.get('token');

Sveltekit Error: `page` in `load` functions has been replaced by `url` and `params`

I am trying to display my date from GraphCMS in my blog application. I receive this error when I go to my single post link (http://localhost:3000/posts/union-types-and-sortable-relations)
"
page in load functions has been replaced by url and params
Error: page in load functions has been replaced by url and params
"
Here is my code
<script context='module'>
export const load = async ({fetch, page: {params}}) => {
const {slug} = params
const res = await fetch(`/posts/${slug}.json`)
if(res.ok) {
const {post} = await res.json()
return {
props: {post},
}
}
}
</script>
<script>
export let post
</script>
<svelte:head>
<title>Emrah's Blog | Welcome</title>
</svelte:head>
<pre>{JSON.stringify(post, null, 2)}</pre>
Can you please help. Thanks
Try using params instead of page: params, though the latter still works in Sveltekit 278 (which I'm using).
Besides, I'm curious to know what makes you prefer this method to querying GraphCMS for your single post. I do it like this:
import {client} from '$lib/js/graphql-client'
import {projectQuery} from '$lib/js/graphql-queries'
export const load = async ({ params }) => {
const {slug} = params
const variables = {slug}
const {project} = await client.request(projectQuery, variables)
return {
props: {
project
}
}
}
Yes, this has been changed a while ago, now the different parts of what used to be page are passed directly into the load function:
export async function load({ fetch, page }) {
const { params, url } = page
}
export async function load({ fetch, params, url }) {
}
Something else to consider is that now there are page endpoints, if your file is [slug].svelte you can make a file [slug].js and add the following:
export async function get({ params }) {
const { slug } = params;
const post = {}; // add the code to fetch from GraphCMS here
return {
status: 200,
body: {
post
}
}
}
With this you can remove the load function and make your code simpler (especially because you technically already have all this code in your /posts/[slug].json.js file.
<script context='module'>
export async function load({ fetch, params}){
let id = params.users
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
const user = await response.json()
if(response.ok){
return {props:{user}}
}
return {
status: response.status,
error : new Error(" sorry no user found")
}
}
export let user

How to get cookies in getServerSideProps NextJS [duplicate]

This question already has an answer here:
Why are cookies not sent to the server via getServerSideProps in Next.js?
(1 answer)
Closed 10 months ago.
In my User page I'm using getServerSideProps to get user's data.
At console.log number 1 you can see that cookies with tokens are exsists.
But at console.log number 2 cookies are empty
Also I did same request inside useEffect
And it works as I expect. And at the console.log number 2 cookies object contains tokens.
How to set cookies for getServerSideProps request?
export async function getServerSideProps({req, res}) {
console.log(1, req.cookies)
const response = await $api.get(`/store/profile/user`, {withCredentials: true})
return { props: {} }
}
const User: NextPage = ({props}) => {
const getData = async () => {
const response = await $api.get(`/store/profile/user`, {withCredentials: true})
}
React.useEffect(() => {
getData()
}, [])
return (
<LoginLayout>
<ProfileLayout>
<UserInfo />
</ProfileLayout>
</LoginLayout>
)
}
export default User
export default async function refresh(req, res, next) {
try {
console.log(2, req.cookies)
const {refreshToken} = req.cookies
const userData = await userService.refresh(refreshToken)
res.cookie("refreshToken", userData.refreshToken, {maxAge: 5 * 24 * 60 * 60 * 1000, httpOnly: true})
return res.json(userData)
} catch (e) {
res.status(e.status).json({message: e.message})
}
}
logs for getServerSideProps request:
1 {
refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InpoZW4uYWxleGVlZmZAZ21haWwuY29t',
token:'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InpoZW4uYWxleGVlZmZAZ21haWwuY29tIiThm'
}
2 {}
logs for request inside useEffect:
2 {
refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InpoZW4uYWxleGVlZmZAZ21haWwuY29ih',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InpoZW4uYWxleGVlZmZAZ21haWwuY29tIiwiaWQg'
}
First install cookie package using npm
npm install cookie
and then import it where you need it
import cookie from "cookie";
and the rest must be something like the following:
export const getServerSideProps = async (context) => {
const mycookie = cookie.parse(
(context.req && context.req.headers.cookie) || ""
);
let cookieNameData = {};
if (mycookie.whatevercookienameis) {
cookieNameData = mycookie.whatevercookienameis;
}
return {
props: {
cookieNameData
}
}
}
Hope it gives you a clear picture how to achieve it.

Error: Error serializing `.data[4].description` returned from `getStaticProps` in "/" [duplicate]

I'm working with Next.js, I tried accessing data but got this error:
Error: Error serializing `.profileData` returned from `getStaticProps` in "/profile/[slug]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
My code:
import { getAllBusinessProfiles } from '../../lib/api';
const Profile = ({ allProfiles: { edges } }) => {
return (
<>
<Head>
<title>Profile</title>
</Head>
<Hero />
<section>
{edges.map(({ node }) => (
<div key={node.id}>
<Link href={`/profile/${node.slug}`}>
<a> {node.businessInfo.name} </a>
</Link>
</div>
))}
</section>
</>
);
}
export default Profile;
export async function getStaticProps() {
const allProfiles = await getAllBusinessProfiles();
return {
props: {
allProfiles
}
};
}
getAllBusinessProfiles from api.js:
const API_URL = process.env.WP_API_URL;
async function fetchAPI(query, { variables } = {}) {
const headers = { 'Content-Type': 'application/json' };
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables })
});
const json = await res.json();
if (json.errors) {
console.log(json.errors);
console.log('error details', query, variables);
throw new Error('Failed to fetch API');
}
return json.data;
}
export async function getAllBusinessProfiles() {
const data = await fetchAPI(
`
query AllProfiles {
businessProfiles(where: {orderby: {field: DATE, order: ASC}}) {
edges {
node {
date
title
slug
link
uri
businessInfo {
name
title
company
image {
mediaItemUrl
altText
}
highlight
phone
city
country
facebook
instagram
email
website
profiles {
profile
profileInfo
}
extendedProfile {
title
info
}
}
}
}
}
}
`
);
return data?.businessProfiles;
};
What could be the error here? I used the getStaticProps method on Next.js but got the error above instead. Please, check. Thanks.
The error:
Server Error
Error: Error serializing .profileData returned from getStaticProps in "/profile/[slug]".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
I don't know what could cause this though.
Add JSON.stringify when calling an asynchronous function that returns an object.
Try modifying your getStaticProps function like this.
export async function getStaticProps() {
const profiles = await getAllBusinessProfiles();
const allProfiles = JSON.stringify(profiles)
return {
props: {
allProfiles
}
};
}
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
Source: MDN
I had this issue using Mongoose and Next.js.
To solve it: I switched from convert require to import then wrapped my result in JSON.parse(JSON.stringify(result));.
Good: import mongoose from 'mongoose';
Bad: const mongoose = require('mongoose');
I had the same serialization error when accessing a Vercel system environment variable in getStaticProps.
Using JSON.stringify did not do the trick, but String() worked. My code:
export async function getStaticProps() {
const deploymentURL = String(process.env.NEXT_PUBLIC_VERCEL_URL);
return {
props: {
deploymentURL,
},
};
}
Thanks to this GitHub issue for the inspiration
I had the same issue when I was working with redux with next js and the reason was one of the fields in the default state I set it to undefined. Instead I used null:
const INITIAL_STATE = {
products: [],
loading: false,
error: undefined,
cart: [],
};
error:undefined was causing the error. Because "undefined" cannot be serialized:
export async function getStaticProps() {
const allProfiles = await getAllBusinessProfiles();
return {
props: {
allProfiles
}
};
}
you are returning "allProfiles" which is the result of async getAllBusinessProfiles() which is either returning undefined, error or one of the fields of the returned object is undefined. "error" object is not serializable in javascript
Instead of using undefined, you have to use null as the value for your variables.
Note that the error shows you exactly which variable is using undefined as its value. Just modify its value to be null.
The value 'undefined' denotes that a variable has been declared, but hasn't been assigned any value. So, the value of the variable is 'undefined'. On the other hand, 'null' refers to a non-existent object, which basically means 'empty' or 'nothing'.
Source: [1]
I was having the same issue while trying to find a match in the array of data using the id. The issue I had was the items in the array had ids which were numbers while the value I was getting from params was a string. So all i did was convert the number id to a string to match the comparison.
export async function getStaticProps({ params }) {
const coffeeStore = coffeeStoreData.find(
(store) => store.id.toString() === params.slug[0]
);
return {
props: {
coffeeStore,
},
};
}
install a package called babel-plugin-superjson-next and superjson and added a .babelrc file with these contents:
{
"presets": ["next/babel"],
"plugins": ["superjson-next"]
}
see this topic : https://github.com/vercel/next.js/discussions/11498.
I had a similar problem too where I was fetching data through apollo directly inside of getStaticProps. All I had to do to fix the error was add the spread syntax to the return.
return {
props: {
data: { ...data }
}
}
return { props: { allProfiles: allProfiles || null } }
In getStaticProps() function, after fetching your data it will be in json format initially, but you should change it as follow:
const res = await fetch(`${APP_URL}/api/projects`);
const data = JSON.parse(res);
now it will work.
When you call api you should use try catch. It will resolve error.
Example:
import axios from "axios";
export const getStaticProps = async () => {
try {
const response = await axios.get("http:...");
const data = response.data;
return {
props: {
posts: data
}
}
} catch (error) {
console.log(error);
}
}
Hope help for you !
put res from API in Curly Brackets
const { res } = await axios.post("http://localhost:3000/api", {data})
return { props: { res } }
try this, it worked for me:
export async function getStaticProps() {
const APP_URL = process.env.PUBLIC_NEXT_WEB_APP_URL;
const res = await fetch(`${APP_URL}/api/projects`);
const projects = await res.json();
return {
props: {
projects: projects?.data,
},
};
}

Next.js Error serializing `.res` returned from `getServerSideProps`

I am getting the error below, when I use getServerSideProps function to retrieve data from Binance API.
import binance from "../config/binance-config";
export async function getServerSideProps() {
const res = await binance.balance((error, balances) => {
console.info("BTC balance: ", balances.BTC.available);
});
return {
props: {
res,
},
};
}
import Binance from "node-binance-api"
const binance = new Binance().options({
APIKEY: 'xxx',
APISECRET: 'xxx'
});
export default binance;
Error output:
Error: Error serializing `.res` returned from `getServerSideProps` in "/dashboard".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
I'm not sure how to resolve this error. I would just like to be able to mine (and display) the response by sending it as props in another component.
Thank you!
Here is how I solved it in NextJs
// Get Data from Database
export async function getServerSideProps(ctx) {
const { params } = ctx;
const { slug } = params;
await dbConnect.connect();
const member = await Member.findOne({ slug }).lean();
await dbConnect.disconnect();
return {
props: {
member: JSON.parse(JSON.stringify(member)), // <== here is a solution
},
};
}
Convert your data into json format when you are fetching it through an Api,
export async function getServerSideProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}`enter code here`
return {
props: {}, // will be passed to the page component as props
}
}
You can read more detail on this link, https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
put res from API in Curly Brackets
const { res } = await binance.balance((error, balances) => {
console.info("BTC balance: ", balances.BTC.available);
});
return {
props: {
res,
},
};
This is actually a simple error. The props that are being returned from getServerSideProps must be wrapped in curly brackets as shown below:
return {props: {res}}
This will clear the serialization error provided no nulls are being returned in response

Categories

Resources