I have a contact form that's a client component in a Nextjs 15 project.
I've integrated Google captcha v3 into my project after following the Google captcha's documentation.
When someone submits the contact form, a submission handler is triggered. This handler calls a function to generate a Captcha token and another function, which is a server action, responsible for sending an email to the website owner.
In the component, I'm using the useActionState hook to be able to translate the server action's state to a better user experience on the frontend through the values of isPending and state.
My component:
const initialState = {
status: 'success',
messages: [],
}
const Contact = () => {
const [state, formAction, isPending] = useActionState(sendEmail, initialState)
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const captchaToken = await getCaptchaToken()
const formData = new FormData(event.currentTarget)
formAction(formData, captchaToken)
}
return (
<div>
<h2>
Contact
</h2>
<form onSubmit={handleSubmit}>
<label>
Name
<input
required
type='text'
name='fname'
placeholder='enter your first name'
/>
</label>
<label>
Email
<input
required
type='email'
name='email'
placeholder='enter your email'/>
</label>
<button>
{isPending ? 'Pending' : 'Submit'}
</button>
{state.messages.length > 0 &&
state.messages.map((message, index) => {
return (
<p
key={index}
>
{message}
</p>
)
})}
</form>
</div>
)
}
The server action:
export async function sendEmail(
prevState: { messages: string[] },
formData: FormData,
captchaToken: string
) {
// Do some logic with the token and the formData
return {
status: 'success',
messages: ['Thank you for contacting us!']
}
}
I’m facing a TypeScript issue with formAction that's in the handleSubmit. I’m getting the error: "Expected 0 arguments, but got 2".
If I remove the captchaToken argument from the formAction function and the sendEmail function signature, the issue disappears.
How can I pass the captchaToken to the formAction function along with the formData so it can be received by sendEmail?
I have a contact form that's a client component in a Nextjs 15 project.
I've integrated Google captcha v3 into my project after following the Google captcha's documentation.
When someone submits the contact form, a submission handler is triggered. This handler calls a function to generate a Captcha token and another function, which is a server action, responsible for sending an email to the website owner.
In the component, I'm using the useActionState hook to be able to translate the server action's state to a better user experience on the frontend through the values of isPending and state.
My component:
const initialState = {
status: 'success',
messages: [],
}
const Contact = () => {
const [state, formAction, isPending] = useActionState(sendEmail, initialState)
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const captchaToken = await getCaptchaToken()
const formData = new FormData(event.currentTarget)
formAction(formData, captchaToken)
}
return (
<div>
<h2>
Contact
</h2>
<form onSubmit={handleSubmit}>
<label>
Name
<input
required
type='text'
name='fname'
placeholder='enter your first name'
/>
</label>
<label>
Email
<input
required
type='email'
name='email'
placeholder='enter your email'/>
</label>
<button>
{isPending ? 'Pending' : 'Submit'}
</button>
{state.messages.length > 0 &&
state.messages.map((message, index) => {
return (
<p
key={index}
>
{message}
</p>
)
})}
</form>
</div>
)
}
The server action:
export async function sendEmail(
prevState: { messages: string[] },
formData: FormData,
captchaToken: string
) {
// Do some logic with the token and the formData
return {
status: 'success',
messages: ['Thank you for contacting us!']
}
}
I’m facing a TypeScript issue with formAction that's in the handleSubmit. I’m getting the error: "Expected 0 arguments, but got 2".
If I remove the captchaToken argument from the formAction function and the sendEmail function signature, the issue disappears.
How can I pass the captchaToken to the formAction function along with the formData so it can be received by sendEmail?
We can use bind for this purpose.
First change your useActionState hook like that
const sendEmailWithCaptchaToken = sendEmail.bind(null, {
captchaToken: "123456abcdef",
})
const [state, formAction, isPending] = useActionState(sendEmailWithCaptchaToken, initialState)
then change your server action like that
export async function sendEmail(
extras: { captchaToken: string },
prevState: { messages: string[] },
formData: FormData,
) {
console.log("extras", extras)
//...
}