NisuformDocs

Next.js forms

A copy-paste Next.js form component that submits to Nisuform from the App Router or the Pages Router, without an API route or server action.

Collect the fields, POST them to your endpoint and check the response. You don't need an API route, a server action or environment variables, because the form key is safe to publish.

Generated for your form

The form's Setup tab, under Code, has this component ready with your endpoint and field names filled in. Your design gives you the styled form from the builder as a component. Your own styles gives you a bare component to style your way.

The component

Forms need state and event handlers, so mark the component as a client component. It works in both the App Router and the Pages Router.

app/contact/ContactForm.jsx
'use client'

import { useRef, useState } from 'react'

export function ContactForm() {
  const shownAt = useRef(Date.now())
  const [status, setStatus] = useState('idle')

  async function onSubmit(event) {
    event.preventDefault()
    setStatus('sending')
    const data = new FormData(event.currentTarget)
    data.set('_elapsed', String(Date.now() - shownAt.current))
    const response = await fetch('https://api.nisuform.com/s/YOUR_FORM_KEY', {
      method: 'POST',
      headers: { Accept: 'application/json' },
      body: data,
    })
    setStatus(response.ok ? 'sent' : 'error')
  }

  if (status === 'sent') {
    return <p>Thanks! We got your message.</p>
  }

  return (
    <form onSubmit={onSubmit}>
      <input type="email" name="email" placeholder="Email" required />
      <textarea name="message" rows={5} required />
      <input type="text" name="_gotcha" tabIndex={-1} autoComplete="off" style={{ display: 'none' }} />
      <button type="submit" disabled={status === 'sending'}>Send</button>
      {status === 'error' && <p role="alert">Something went wrong. Please try again.</p>}
    </form>
  )
}

Use it on a page

Render it from any page. The page itself can stay a server component.

app/contact/page.jsx
import { ContactForm } from './ContactForm'

export default function ContactPage() {
  return <ContactForm />
}

What it does

  • Sends Accept: application/json, so Nisuform answers with JSON instead of the thank-you page. See JavaScript and fetch.
  • Adds _elapsed, the time the form was open, and keeps the hidden _gotcha honeypot empty. Both feed spam protection. See Special fields.
  • Shows a success message when the submission is accepted, and an error when it isn't.

When a server action is worth it, and a version that works with output: 'export', are in the Next.js contact form guide.