Netlify Form using NextJS 13.5.5 - 405 Method Not Allowed

Hello,
I am new to React/NextJS - I have not encountered any issues with Netlify this far and likely i am doing something wrong but i cannot understand what. I have followed a few tuorials and documents but to no avail.

I have turned on Form Detection
Below is a screenshot of my directory, if it helps

Here is the code for my form, which displays but does not work on my site:

"use client";
const ContactForm = () => {
    return (
        <section className="py-16 md:py-32 relative overflow-x-hidden" id="contact">
            <div className="container ">
                <div className="relative z-30">
                    <form 
                        name="contact" 
                        method="POST" 
                        data-netlify="true"
                    >
                        <p>
                            <label>Your Name:
                                <input 
                                    type="text" 
                                    name="name" 
                                />
                            </label>
                        </p>
                        <p>
                            <label>Your Email: 
                                <input 
                                    type="email" 
                                    name="email"
                                />
                            </label>
                        </p>
                        <p>
                            <label>Message: 
                                <textarea name="message"></textarea>
                            </label>
                        </p>
                        <p>
                            <button type="submit">Send</button>
                        </p>
                    </form>
                </div>
            </div>
        </section>
    );
};

export default ContactForm;

@Decisive-Development You could see:
https://nextjs-platform-starter.netlify.app/classics

Which links to this example repo:
https://github.com/netlify-templates/next-platform-starter

The relevant files are:
https://github.com/netlify-templates/next-platform-starter/blob/main/components/feedback-form.jsx
https://github.com/netlify-templates/next-platform-starter/blob/main/public/__forms.html

1 Like

Ok so i got the form deployed, however when i submit the form i get a 502 error :

https://decisive-development.com/public/_forms.html 502 (Bad Gateway)

I used the files and code you suggested. The only things i changed was:

  • The name of feeback-form to FeedbackForm
  • The path to _forms.html

All relevent files in the screenshot below, marked with red for ease of reading

Appreciate your help, this is certainly an improvement thus far

Looks like it is being found, just an issue with submission

@Decisive-Development The static form file serves a few purposes:

  1. Ensures there is a HTML form that Netlify can parse on completion of the build
  2. Ensures there is a static route that can be posted to that isn’t being handled by Next

It’s being detected because Netlify is finding the form in the files resulting from your build.

It’s not being received because the route you’re posting to is incorrect.

As you mention, you’ve changed it to:
https://decisive-development.com/public/_forms.html

Visit that, and you’ll see it’s a 404.

That’s because the file will be getting shifted from your public folder to your output folder during the build, and since it’s at the root of your public folder it will likewise be at the root of your deployment.

So the file is actually here:
https://decisive-development.com/_forms.html

Change your fetch request so that it submits to /_forms.html

2 Likes

Amazing, thank you for the clear explaination and solution. I’ve got it working now - massively appreciated Nathan!

You’re welcome, I don’t work with Next myself, but I see this come up fairly frequently.

Hopefully Netlify can update the documentation somewhere/somehow to assist those working with Next to more clearly understand the additional hurdles they have to jump to work with Netlify forms.

Another thing to be wary of is redirects, as they don’t necessarily play nicely with systems that insert themselves in before them, e.g.

Hi Nathan,

Following on from your help. I wanted to amend the message Input to be a textarea, for better UX/UI - however after making the changes i get 404 submissions

<html>
    <head></head>
    <body>
        <form name="feedback" data-netlify="true" hidden>
            <input type="hidden" name="form-name" value="feedback" />
            <input name="name" type="text" />
            <input name="email" type="text" />
            <textarea name="message" ></textarea>
        </form>
    </body>
</html>
'use client';
import Tilt from 'react-parallax-tilt';
import { useState } from 'react';
import { Card } from './Card';

export function FeedbackForm() {
    const [status, setStatus] = useState(null);
    const [error, setError] = useState(null);

    const handleFormSubmit = async (event) => {
        event.preventDefault();
        try {
            setStatus('pending');
            setError(null);
            const myForm = event.target;
            const formData = new FormData(myForm);
            const res = await fetch('/_forms.html', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                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 (
        <div>
            <Tilt
                className="relative z-20 bg-theme-secondary-background py-10 px-5 rounded-3xl border border-theme-complementary border-opacity-30"
                glareEnable={true}
                glareMaxOpacity={0.2}
                glareColor="#e27868"
                glarePosition="all"
                glareBorderRadius="24px"
                tiltMaxAngleX={1}
                tiltMaxAngleY={1}
            >
                <Card title="Get In Touch">
                    <form
                        name="contact"
                        onSubmit={handleFormSubmit}
                        className="grid grid-cols-2 gap-5 w-[500px]"
                    >
                        <input
                            type="hidden"
                            name="form-name"
                            value="contact"
                        />
                        <input
                            name="name"
                            type="text"
                            placeholder="Name"
                            required
                            className="text-theme-primary input-placeholder p-2 bg-theme-complementary col-span-1"
                        />
                        <input
                            name="email"
                            type="text"
                            placeholder="Email"
                            required
                            className="text-theme-primary input-placeholder p-2 bg-theme-complementary col-span-1"
                        />
                        <textarea
                            name="message"
                            placeholder="Message"
                            required
                            className="text-theme-primary input-placeholder p-2 h-40 col-span-2 bg-theme-complementary"
                            style={{ overflow: 'auto', resize: 'none' }} // Prevents user from resizing the textarea
                        />
                        <button
                            className="bg-theme-primary text-white font-semibold py-2 px-4 border rounded transition ease-in-out duration-300 relative blue z-20 w-40 block text-center font-code uppercase tracking-wider reactive border-theme-blue ml-auto col-span-2"
                            type="submit"
                            disabled={status === 'pending'}
                        >
                            Submit
                        </button>
                        {status === 'ok' && (
                            <div className="alert alert-success">
                                <SuccessIcon />
                                Submitted!
                            </div>
                        )}
                        {status === 'error' && (
                            <div className="alert alert-error">
                                <ErrorIcon />
                                {error}
                            </div>
                        )}
                    </form>
                </Card>
            </Tilt>
        </div>
    );
}

function SuccessIcon() {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            className="stroke-current shrink-0 h-6 w-6"
            fill="none"
            viewBox="0 0 24 24"
        >
            <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
            />
        </svg>
    );
}
function ErrorIcon(success) {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            className="stroke-current shrink-0 h-6 w-6"
            fill="none"
            viewBox="0 0 24 24"
        >
            <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
            />
        </svg>
    );
}

This is because you didn’t ONLY change the input.

Stepping through reveals the issue…

Using your form to do the POST results in the 404:

Visiting the same static HTML URL directly with a standard GET results in:

The payload values submitted by the POST were:

Viewing the source of the form shows as you supplied above:

The name of the form is different, and contact !== feedback.

Netlify will be rejecting POST’s to form names that do not exist and responding with 404.

Ensure the form-name is consistent in all places.