#Server-side implementation

1 messages · Page 1 of 1 (latest)

arctic plaza
#

I am building a webapp with:
Frontend: NextJS14 App Router, React in Typescript
Backend: ExpressJS, MongoDB.

For a protected route, server-side rendered in NextJS, let's say under src/app/account/page.tsx
Let's say this page, will have this component:

`
import React from 'react';

import { fetchEligibility() } from '../server-functions/fetchEligibility';

async function Account() {
const eligibile = await fetchEligibility();
if (eligibile){
return <EligibleComponent />
} else {
return <UneligibleComponent />
}
}

export default Account`

Lets say the fetchEligibility() determines that this session is eligible to access the page, but has outdated cookies and wants to update them, so it want to set some cookies on the client-side, since this is a server-side function being executed in NextJS, how can we achieve this?

jovial cedarBOT
#

Hi @arctic plaza. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In Next.js, you can set cookies in Server Actions or Route Handlers using the cookies function. However, HTTP does not allow setting cookies after streaming starts, so you cannot set cookies from a page or layout directly. You can also set cookies from Middleware.

Here's an example of how you can set cookies in a Route Handler:

import { cookies } from 'next/headers'
 
export async function GET(request: Request) {
 const cookieStore = cookies()
 const token = cookieStore.get('token')
 
 return new Response('Hello, Next.js!', {
 status: 200,
 headers: { 'Set-Cookie': `token=${token.value}` },
 })
}

You can also use the underlying Web APIs to read cookies from the request:

import { type NextRequest } from 'next/server'
 
export async function GET(request: NextRequest) {
 const token = request.cookies.get('token')
}

In a Server Action, you can get, set, and delete cookies using the cookies API:

'use server'
 
import { cookies } from 'next/headers'
 
export async function exampleAction() {
 // Get cookie
 const value = cookies().get('name')?.value
 
 // Set cookie
 cookies().set('name', 'Delba')
 
 // Delete cookie
 cookies().delete('name')
}

However, it's important to note that Server Actions can only be called from the client, because they need to generate an RPC layer to function. If you try to call them from the server, you can basically call the same function without the "use server" directive because it gives you roughly the same result.

For more information, you can refer to the following sources:

#

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@arctic plaza kapa.ai is still learning and improving, please let us know how it did by reacting below

arctic plaza
#

@jovial cedar
I have a Server Component Page, that is fetching data before rendering. This data fetching is using a function, this function is calling an ExpressJS API Route, receiving cookies, i want this function to set the cookies back to the client.

jovial cedarBOT
#

Let me check the knowledge base for you. One moment! :books:

#

In Next.js, you can set cookies inside an API Route using the setHeader method on the response. Here's an example:

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default async function handler(
 req: NextApiRequest,
 res: NextApiResponse
) {
 res.setHeader('Set-Cookie', 'username=lee; Path=/; HttpOnly')
 res.status(200).send('Cookie has been set.')
}

(Source: Next.js Docs (https://nextjs.org/docs/pages/building-your-application/data-fetching/forms-and-mutations#setting-cookies))

However, setting cookies from a server component during a server-side render is not directly possible. This is because the Set-Cookie header won't be accounted for during the rendering.

One workaround is to make the fetch request client-side, such as in a useEffect hook. This way, the response object would make its way back to the browser where it can set the cookies appropriately. For this, you may have to use credentials: 'include' in the fetch request.

useEffect(() => {
  fetch('<http://localhost:3000/api/session',> { cache: 'no-store', credentials: 'include' })
    .then(response => response.json())
    .then(data => console.log(data));
}, []);

(Source: Github Issue (https://github.com/vercel/next.js/issues/52799))

Remember, you may have to run this locally to notice cookies being set.

If you're still having trouble, please refer to the Next.js documentation (https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options) or consider opening a new issue on the Next.js GitHub (https://github.com/vercel/next.js/issues) with a reproduction so the community can investigate your case.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: