The netlify form submission POST request returns 404

Form url: https://local-shops.netlify.app/contact-us
Hidden form in public directory: https://local-shops.netlify.app/__forms.html

I followed a solution presented in this topic https://answers.netlify.com/t/netlify-form-submission-not-working/116648 with an example found here https://github.com/netlify-templates/next-platform-starter/blob/main/components/feedback-form.jsx

My hidden form __forms.html in public directory:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <title>Title</title>
</head>
<body>
<!-- A little help for the Netlify post-processing bots -->
<form name='contact-us' netlify netlify-honeypot='bot-field' hidden>
  <input type='hidden' name='form-name' value='contact-us' />
  <input type='text' name='name' />
  <input type='email' name='email' />
  <textarea name='message'></textarea>
</form>
</body>
</html>

My react component ContactUsForm.jsx:

'use client'

import { useReducer } from 'react'
import { toast, ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'

const ON_FORM_CHANGE = 'ON_FORM_CHANGE'
const RESET_FORM = 'RESET_FORM'

const initialFormState = { name: '', email: '', message: '' }

const formReducer = (state, action) => {
  switch (action.type) {
    case ON_FORM_CHANGE:
      return { ...state, [action.field]: action.payload }
    case RESET_FORM:
      return { ...initialFormState }
    default:
      return state
  }
}

export default function ContactUsForm() {
  const [formState, dispatch] = useReducer(formReducer, initialFormState)
  const { name, email, message } = formState

  const onFieldChange = (e) => {
    dispatch({
      type: ON_FORM_CHANGE,
      field: e.target.name,
      payload: e.target.value,
    })
  }

  const onFormSubmit = (e) => {
    e.preventDefault()

    fetch('/__forms.html', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams(formState).toString()
    })
      .then(() => {
        toast.success('Message received! We\'ll get back to you shortly!')
        dispatch({ type: RESET_FORM })
      })
      .catch(error => {
        toast.error('Uh-oh, something went wrong...')
        console.error(e)
      });
  }

  return (
    <div>
      <form name='contact-us' onSubmit={onFormSubmit}>
        <input type='hidden' name='form-name' value='contact-us' />
        <h1 className='text-4xl font-bold py-2'>Let's talk.</h1>
        <p className='text-xl py-2'>Tell us what you're struggling with. We're happy to help!</p>
        <div className='flex flex-col py-2 rounded-md items-center gap-y-5'>
          <div className='flex flex-col justify-evenly w-full gap-y-5'>
            <input
              type='text'
              name='name'
              required
              onChange={onFieldChange}
              value={name}
              placeholder='Name'
              className='appearance-none border w-full p-4 text-gray-700 leading-tight bg-light-grey text-sm rounded-md'
            />
            <input
              type='email'
              name='email'
              required
              onChange={onFieldChange}
              value={email}
              placeholder='E-mail Address'
              className='appearance-none border w-full p-4 text-gray-700 leading-tight bg-light-grey text-sm rounded-md'
            />
            <textarea
              name='message'
              onChange={onFieldChange}
              value={message}
              placeholder='Message'
              className='appearance-none border h-full w-full p-4 text-gray-700 leading-tight bg-light-grey text-sm rounded-md'
            ></textarea>
          </div>
          <button
            type='submit'
            className='focus:outline-none focus:shadow-none shadow-lg hover:shadow-xl transition ease-in-out duration-300 transform hover:scale-103 bg-black text-white rounded block text-center py-2 px-4 w-full'
          >
            Send Message
          </button>
        </div>
      </form>
      <ToastContainer />
    </div>
  )
}

Error:

@john_ngo You are failing to send the form-name:

image

It’s a requirement as mentioned here:

When submitted with the form-name it works:

image

1 Like

awesome, thank you so much!