#Why does NextJS say this is a client component?

1 messages · Page 1 of 1 (latest)

wooden steppe
#

I'm getting the following error, but I don't understand why NextJS thinks this is a client component. I even have 'use server' at the top of the file

Error: 
  × It is not allowed to define inline "use server" annotated Server Actions in Client Components.
  │ To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.
  │ 
  │ Read more: https://nextjs.org/docs/app/api-reference/functions/server-actions#with-client-components
  │ 
    ╭─[/..../nextjs/app/tenants/add-form.tsx:8:1]
  9 │     
 10 │     export async function AddForm() {
 11 │ ╭─▶     async function createTenant(prevState: any, formData: FormData) {
 12 │ │           'use server'
 13 │ 
 14 │ │           ..... do stuff to create the tenant, call APIs, etc
 40 │ ╰─▶       }
 41 │     
 42 │         return (
 43 │             <form name="newtenant" id="newtenant" action={createTenant}> 
    ╰────

API Reference for Next.js Server Actions.

icy fableBOT
#

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

#

The error message you're seeing is due to the way you're defining your Server Action within a Client Component. In Next.js, Server Actions can be defined in two places:

  1. Inside the component that uses it (Server Components only).
  2. In a separate file (Client and Server Components), for reusability. You can define multiple Server Actions in a single file.

In your case, you're trying to define a Server Action (createTenant) inside a Client Component (AddForm). This is not allowed in Next.js.

To resolve this issue, you have two options:

  1. Move the createTenant function to a separate file with the "use server" directive at the top of the file. Then, import the Server Action into your Client Component. Here's an example:
// app/actions.js
'use server'
 
export async function createTenant(prevState: any, formData: FormData) {
 // ... do stuff to create the tenant, call APIs, etc
}

// app/tenants/add-form.tsx
'use client'
 
import { createTenant } from '../actions'
 
export default function AddForm() {
 return (
 <form name="newtenant" id="newtenant" action={createTenant}> 
 // ...
 )
}
  1. Pass the Server Action down through props from a Server Component. Here's an example:
// app/parent-component.tsx
'use server'
 
export async function createTenant(prevState: any, formData: FormData) {
 // ... do stuff to create the tenant, call APIs, etc
}

export default function ParentComponent() {
 return (
 <AddForm createTenant={createTenant} />
 )
}

// app/tenants/add-form.tsx
'use client'
 
export default function AddForm({ createTenant }) {
 return (
 <form name="newtenant" id="newtenant" action={createTenant}> 
 // ...
 )
}