Netlify Form Submission Not Working

My netlify form isn’t working. I have read up on how to implement this using a static site generator but I still can’t get it to work.

I have a form here: https://shark-staffing.netlify.app/contact

I created a hidden form and put it in my public dir here: https://shark-staffing.netlify.app/contact-form.html

My post processing step looks like this

4:02:28 PM: Detected form fields:

  • bot-field
  • name
  • phone
  • email
  • fileUpload
  • message

But I still cannot see my form submission. I am using next 14 and the app directory. What am I doing wrong?

Thx

@tomdilello If you post to the /contact-form route (which is a known static HTML page), and not the /success route (which is handled by next.js), it should work.

I adjusted your static html form like this:

  • Made it visible
  • Added a submit button
  • Changed the action to /contact-form

Upon submitting that with test information:

I receive:

image

You should also see that submission in the UI in Netlify.

1 Like

Cool I do see the submissions in the UI now. However I can’t have our users fill out this form. I need them to be able to fill out the form on the contact page listed above. The code for the above contact form looks like this.

<form
            name='contact-form'
            method='POST'
            data-netlify='true'
            data-netlify-honeypot='bot-field'
            className='grid grid-cols-1 justify-start p-4'
            action='/success'
          >
            <FormParagraph>
              <label htmlFor='name' className='mr-2'>
                Name:
              </label>
              <input id='name' type='text' name='name' className='w-full' />
              <input type='hidden' name='bot-field' />
              <input type='hidden' name='form-name' value='contact-form' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='phone' className='mr-2'>
                Phone:
              </label>
              <input id='phone' type='text' name='phone' className='w-full' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='email' className='mr-2'>
                Email:
              </label>
              <input id='email' type='email' name='email' className='w-full' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='resume'>Resume:</label>
              <input type='file' id='resume' name='fileUpload' accept='.pdf, .doc, .docx'></input>
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='message' className='mr-2'>
                Message:
              </label>
              <textarea id='message' name='message' />
            </FormParagraph>
            <p>
              <button type='submit' className='w-20'>
                Send
              </button>
            </p>
          </form>

Do I need to change this form’s code to point to /contact-form.html?

@tomdilello I wasn’t suggesting that you have your users fill out that form, I was using it as a readily available minimum reproduction to prove that posting to a known static file route causes Netlify to receive the submission.

How you perform the actual form implementation is up to you, I’m just advising that you cannot submit the data to the /success page.

Since you’re working with Next I presume you’re familiar with JavaScript.
You could leverage some JavaScript to submit the form.

  • Retrieve the form values
  • Make a fetch call to submit them to any know static route on your site, (for example /contact-form)
  • Show a success message or do a redirect upon success

I don’t work with Next, so cannot advise on “Next specific ways of doing things”, but you could google around.

There’s a new example on how to use forms (and other things) with Next.js App Router - see live demo which also explains the solution. The source for the form is here.
The idea is:

  1. The form definition is in a static file - this is only used for Netlify detecting the forms on deploy
  2. The form itself has an onSubmit handler in code rather than an action - the handler makes a fetch request to submit the form.
1 Like

Ah, simple enough. I will give this a try and get back. Thanks!

EDIT: Ok just tried this but I am now getting a 405 Method Not Allowed

Here is my code

'use client';

import Image from 'next/image';
import Link from 'next/link';
import React, { useState } from 'react';

import { MobilePhone } from '../components/icons';
import { FormParagraph, LinkedIn, MapPin } from './components';

export default function Contact() {
  const [status, setStatus] = useState<string>('');
  const [error, setError] = useState<string>('');

  // @ts-ignore
  const handleFormSubmit = async (event) => {
    event.preventDefault();
    try {
      setStatus('pending');
      setError('');

      const myForm = event.target;
      const formData = new FormData(myForm);

      const res = await fetch('/__contact-form.html', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        // @ts-ignore
        body: new URLSearchParams(formData).toString(),
      });

      if (res.status === 200) {
        setStatus('ok');
      } else {
        setStatus('error');
        setError(`${res.status} ${res.statusText}`);
      }
    } catch (e) {
      setStatus('error');
      setError(`${e}`);
    }
  };

  return (
    <section className=' w-full p-4 md:m-auto md:w-3/4'>
      <div className='grid grid-cols-1 md:grid-cols-2'>
        <div id='col-1' className='prose p-0 md:border-r md:border-r-neutral-300 md:p-4'>
          <h1>Get in touch</h1>
          <h3>We&apos;d love to hear from you!</h3>
          <form name='contact-form' className='grid grid-cols-1 justify-start p-4' onSubmit={handleFormSubmit}>
            <FormParagraph>
              <label htmlFor='name' className='mr-2'>
                Name:
              </label>
              <input id='name' type='text' name='name' className='w-full' />
              <input type='hidden' name='bot-field' />
              <input type='hidden' name='form-name' value='contact-form' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='phone' className='mr-2'>
                Phone:
              </label>
              <input id='phone' type='text' name='phone' className='w-full' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='email' className='mr-2'>
                Email:
              </label>
              <input id='email' type='email' name='email' className='w-full' />
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='resume'>Resume:</label>
              <input type='file' id='resume' name='fileUpload' accept='.pdf, .doc, .docx'></input>
            </FormParagraph>
            <FormParagraph>
              <label htmlFor='message' className='mr-2'>
                Message:
              </label>
              <textarea id='message' name='message' />
            </FormParagraph>
            <p>
              <button type='submit' className='w-20'>
                Send
              </button>
            </p>

            {status === 'ok' && <div className='text-green-700'>Submitted!</div>}
            {status === 'error' && <div className='text-red-700'>{error}</div>}
          </form>
        </div>
        <div id='col-2' className='prose border-t border-r-neutral-300 pt-4 md:border-none md:py-4 md:pl-8 md:pr-4'>
          <Image src='/images/clt-contact.jpg' alt='Charlotte skyline' width={300} height={168} />
          <h3>Shark Staffing</h3>
          <ul>
            <li className='grid grid-cols-[26px_1fr]'>
              <div className='my-auto'>
                <MapPin />
              </div>
              <div className='my-auto p-2'>Charlotte, NC</div>
            </li>
            <li className='grid grid-cols-[26px_1fr]'>
              <div className='my-auto'>
                <MobilePhone />
              </div>
              <div className='my-auto p-2'>
                <Link href='tel:252-531-3209'>252-531-3209</Link> / bcox@shark-staffing.com
              </div>
            </li>
          </ul>
          <h3>Social</h3>
          <ul className='list-none'>
            <li>
              <Link href='https://www.linkedin.com/company/shark-staffing/?viewAsMember=true' target='_blank'>
                <LinkedIn />
              </Link>
            </li>
          </ul>
          <div className='not-prose absolute right-0 z-[-10] hidden opacity-95 md:block'>
            <Image
              src='/images/shark-fin-white.webp'
              alt='Wave crashing on the shore'
              className='relative'
              width={350}
              height={350}
            />
          </div>
        </div>
      </div>
    </section>
  );
}

Here is my dummy contact form again:

<html>
  <head></head>
  <body>
    <form
      name='contact-form'
      method='POST'
      data-netlify='true'
      data-netlify-honeypot='bot-field'
      hidden>
        <input type='hidden' name='bot-field' />
        <input type='hidden' name='form-name' value='contact-form' />
        <input id='name' type='text' name='name' />
        <input id='phone' type='text' name='phone' />
        <input id='email' type='email' name='email' />
        <input type='file' id='resume' name='fileUpload' accept='.pdf, .doc, .docx'> />
        <textarea id='message' name='message'></textarea>
    </form>
  </body>
</html>

@tomdilello The Netlify provided solution is as I’d outlined.

The reason that it’s still not working for you, (with the 405 Method Not Allowed error), is because while you’ve implemented their ajax code for the form submission, you’ve not moved your “static form” or adjusted the URL that it performs the POST to.

Their code assumes the form file is at /__contact-form.html, but that is not a file that exists on your site:

https://shark-staffing.netlify.app/__contact-form.html

You still have:

https://shark-staffing.netlify.app/contact-form.html

So you need to adjust one or the other.

Either adjust the POST so that it is sent to /contact-form
or
Move the form file so it is at /__contact-form.html

1 Like

I see, I was running this locally and it was throwing that error. Once I deployed it it started to work. Thanks so much for your help!

Thank you for letting us know this has been resolved! We appreciate it!

Sorry to resurrect this thread but I just noticed that file uploads are not working as expected. My code is the same as above. Is there something special I have to do?

@tomdilello It may not be the only thing that’s wrong, but I’d imagine that if you largely copied & pasted the code that Netlify provided, that the Content-Type header sent by the fetch is incorrect for your use case.

Many of the answers in this Stack Overflow suggest not adding a Content-Type header at all, so that it’s added automatically as multipart/form-data:

multipart/form-data being what you have specified against your static html form as per Netlify’s documentation here:

For the love of all things good, please put this information in your Forms documentation :face_with_head_bandage:

1 Like

Hi, @darvanen. Isn’t this already in the forms documentation here?

Submit HTML forms with AJAX

@luke not really. All of the examples on that page submit to /.

I was replying specifically to the post on 17 Apr about the “new example on how to use forms … with Next.js” but I see the reply function didn’t include any of the post (sorry, didn’t know, my first post).

We had a working Next.js implementation which broke when we upgraded a major version of Next.js and I spent a lot of time first in the documentation, and then combing forums before I found that example. The key of course was submitting to “known static path” (/__forms.html or wherever you place your form in the public folder) but with Next.js creating a SSG version of / I thought the application was already doing that.

So, even one line explaining that SSG doesn’t necessarily mean it’s treated as a static path would be very helpful, or even better, a link to that resource.

Apologies for the frustrated tone of my comment yesterday, I was, well, frustrated :sweat_smile:

1 Like

Thanks for surfacing this feedback with us. I have informed our docs team to investigate.

1 Like

Thanks for raising this, @darvanen!

We’ve updated the documentation to include a note about this change on our forms troubleshooting page and in the breaking changes of the new Next runtime page.