acjay
acjay

Reputation: 36581

Directly invoke a Server Action from a Server Component in NextJS

I need to set a cookie in a Server Component route. This is not directly possible, but it can be done from Server Actions and Routes. I can't figure out how to invoke a Server Action from a Server Component. Server Actions can be invoked as Form Actions or as though they were regular async functions from Client Components, but attempting to call it as an async function from a Server Component is resulting in:

Unhandled Runtime Error

Error: Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options

Presumably this is because NextJS is not converting the function call to a POST request under the hood. Is there a way to invoke the action in a simple way, or do I need to just go ahead and explicitly create a route and use fetch to invoke it?

page.tsx:

import { cookies } from "next/headers";

export default async function ServerActionFromServerComponent() {
  async function serverAction() {
    "use server";
    cookies().set("serverAction", "cookieValue");
  }

  await serverAction();

  return <div>Hello</div>;
}

Upvotes: 4

Views: 679

Answers (1)

un4ss1gn3d
un4ss1gn3d

Reputation: 13

You can use a NextJs middleware for that. You can go with NextResponse.next() to have default logic (no redirects, etc)

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
  const response = NextResponse.next()

  const cookieStore = request.cookies

  response.cookies.set("serverAction", "cookieValue", {
        domain: ...,
        expires: ...,
        httpOnly: ...,
        maxAge: ...,
        path: ...,
        sameSite: ...,
        secure: ...
      })

  return response
}

export const config = {
  matcher: '/admin/panel',
}

Links:

https://nextjs.org/docs/app/building-your-application/routing/middleware

https://github.com/nextauthjs/next-auth/issues/8254#issuecomment-1690474377

Upvotes: 0

Related Questions