Form actions with a redirect don't submit form data

Netlify site: https://netlify-form-redirect-test.netlify.app
GitHub repo: GitHub - cinnamonKale/netlify-form-redirect-test

Hi, I’ve spent some time debugging an issue with Netlify form data not submitting, and the cause is related to the form action and whether it’s redirected bynetlify.toml.

The test site has a redirect from /test to /#test, something I’ve used for single-page sites to make external linking easier.

When <form action="/#test/" .../>, the form submits as intended.

When <form action="/test/" .../>, which redirects to /#test, the form doesn’t submit to Netlify, but the redirect still works correctly.

The fix for my use case is simple enough: just change the form action to the non-redirecting path. But I can see this being a bigger issue for sites that may dynamically redirect based on localization or some prior user data.

Is this behavior a bug or intentional for Netlify forms? Should this be added to the form docs as a gotcha with more complex sites?

Thanks!

Welcome to the forums @cinnamonKale

Unfortunately I was unable to reproduce your results, with both forms submitting as I believe was intended.

test-submit

@coelmay thanks for adding the attachment. The form looks correct for the user (submits and reloads the page) but on the backend the data never shows up for the second, named contact-2. So the user never knows it didn’t work.

Thanks for (re-) clarifying. Have you checked the “Spam submissions” section? I dummied up a couple of forms to mimic yours and in all cases the submissions were marked as spam.

Yep, spam is empty too. No data is coming through on that form.

I also tried changing the action to the “working” one and submissions then came through, then back to the “not working” action and they stopped working again. The repo narrows the issue down to how the redirect in netlify.toml affects the form action data

In my testing (of your repo) this works.

[[redirects]]
  from = "/test"
  to = "/#test"
  status = 301
  force = true

@coelmay can you provide a screenshot of the submission in Netlify? Or can you provide any other changes to the repo that caused it to work?

I added force = true to the redirect file here but contact-2 still didn’t collect the data in Netlify in either the verified or spam sections

I was wrong. Still doesn’t work.

However, if the page actually exists, it does (as I did in my original test.) This leads me to suspect that a 404 is getting returned on the form submission hence why it is not posting. But this is only a guess.

If you do this,

[[redirects]]
  from = "/test"
  to = "/#test"
  status = 200
  force = true

You get this.

But you also get the default Netlify Thank you! page because the page /test does not exist.

Edit:

When using Netlify forms with SPAs (as you alluded to in your original post) there is a section of the docs dealing with Work with JavaScript-rendered forms which links to How to Integrate Netlify Forms in a Vue App which includes the handling of routes. If you had a redirect rule it would likely take the form of

/*    /

because you would want your app to handle routing and redirects.

As is used as example in the aforementioned blog post Netlify handles submission using axios.post(). If you didn’t wish to use Netlify forms, another option is to use a function to handle for submission meaning there is no redirecting taking place. In Vue something like

<form @submit.prevent="submitForm()" ...>
 ...
</form>

<script>
export.default {
  data () {
    return {
      formdata: {
        ...
      }
    }
  },
  methods: {
    async submitForm() {
      const res = fetch('/.netlify/functions/postformdata', {
        method: 'POST',
        body: formdata
      })
      // rest of function...
    }
  }
}
</script>

@coelmay that’s interesting, so it seems like the cause of the lost data is somewhere in the 301 redirect not passing through POST data. That would be an issue for any POST redirect then, wouldn’t it?

The client-side form handling is a workaround if you’re using something like React or Vue. My use-case is a static HTML file so that workaround wouldn’t apply.

Maybe this isn’t an issue many people encounter, but it’s worth putting in the docs at least that 301 redirects on your form action won’t pass the form data through

It would would seem that is the case. I cannot say if this is by design, a limitation on the redirect/POST mechanism, or a bug.

I don’t believe so.

I wonder why you have/need this redirect in place anyway? Remember that having a #something on a page e.g.

<a href="#about">About</a>

takes you to an anchor on the page you are browsing while having

<a href="/#about">About</a>

will take you to the anchor on the root page (index.html in this case) from any other page while having

<a href="/about">About</a>

will take you to the about page (ie. /about/, /about, or /about.html depending on how your URLs are configured.) So I would say that the redirect you have is entirely not a “normal” or “standard” way of doing things (VueJS Router for example does use # in paths, but all routing is handled internally, not by Netlify’s redirects.)

This seems like a edge-case to me, so I will leave that up to Netlify to pass judgement on.

@coelmay agreed. If the 301 redirect issue can be submitted as a bug request that would resolve the root of this topic, regardless of whether it’s intended behavior

Hey @cinnamonKale ,

You’ll want to bear this in mind:

We can definitely get an issue filed for this. Can’t promise any quick fixes, mind you! Would a 200/proxy rule work, with client-side routing, be a suitable workaround for your use case?

@Scott that’s a good point about redirecting fragments. I haven’t tested this, but I wonder if a 301 redirect like from /page1 to /page2 would also fail to pass the POST data through. It’s definitely worth looking into.

For my use case the fix is just to use the right action without going through the redirect. That’s way simpler than a workaround or including a framework for client-side routing. But if others are having this issue they may not have as easy of a fix

Hi @cinnamonKale,

Yes, I believe form actions are not supposed to be redirected anywhere. It’s a question of which route ends up getting the data. If the form action doesn’t receive the data (lost due to redirect), the submission won’t work.

@hrishikesh thanks for the confirmation! That seems like it should be included in the Forms docs as a potential issue or a gotcha, otherwise people won’t know why their forms aren’t working if it happens to use a redirect in the action

I would agree in principal if this was a common thing; however I am not sure it is (have seen no evidence.) It does mention in the Redirect options docs that 307 Temporary Redirect is currently not supported and to use 302 instead.

In this situation (where a POST redirect is use) a 307 Temporary Redirect is ideal. As per MDN docs

The method and the body of the original request are reused to perform the redirected request.

As written in MDN 302 Found docs

Even if the specification requires the method (and the body) not to be altered when the redirection is performed, not all user-agents conform here - you can still find this type of bugged software out there. It is therefore recommended to set the 302 code only as a response for GET or HEAD methods and to use 307 Temporary Redirect) instead, as the method change is explicitly prohibited in that case.

which explains why (currently) a 302 fails to submit the form data. The same is stated in the 301 Moved Permanently (with a exception of using a 308 Permanent Redirect instead of a 307.)

This is certainly not a cut and dry issue.

1 Like