Vue.js form with prerender shows existing form, but keeps sending back 404, could be a redirect issue?

Hi,

I’ve read through the forum as much as I could but I cannot seem to find a solution. Started here: [Common Issue] Form problems, form debugging, 404 when submitting, Went through all the steps, but so far no dice.

The form is shown under my forms, but I keep getting 404 when I post to it. I’m using https://github.com/chrisvfritz/prerender-spa-plugin/ as suggested in the getting started tutorial.

Below is my HTML.

<template>
  <div class="body">
    <div class="main">
      <div class="logo">
        <h1>Visszajelzés küldése</h1>
      </div>
      <form class="form1" name="feedback" method="POST" action="/feedback/success" data-netlify="true" netlify-honeypot="bot-field">
        <input type="hidden" name="bot-field"/>
        <textarea class="un" name="feedback-text" v-focus v-model="feedbackText"/>
        <button type="submit" class="submit" :disabled="feedbackText.length < 5" >
          Küldés
        </button>
      </form>
    </div>
  </div>
</template>

First I thought it might have something to do with my ‘catch-all’ SPA routing setup, but since then I’ve added a redirect to the /feedback route, to prevent it being caught by the catch-all redirect, but still no dice.

/api/*  https://<my-backend-domain>.com/api/:splat  200
/feedback/* /feedback/:splat 200
/*  /  200

Thanks in advance.

Hey @mannabee! You shouldn’t need those redirects, but you may need to follow the “Reactive forms in Vue” section of @divya’s tutorial (I’m guessing that’s the one where you read about prerender plugin, but let us know if you’re working from another one) since your form is a bit more complicated than just straight inputs. I believe you’ll also need a bit of client-side routing to route to the success form. The way I’ve done it is with Vue’s $router.push, and there’s a code sample here if you want take a look:

Let us know if that works for you or if we can help further!

Hi @jen!

Thanks for getting back to me!

I followed this tutorial by @divya https://www.netlify.com/blog/2018/09/07/how-to-integrate-netlify-forms-in-a-vue-app/ so I’m guessing we’re talking about the same one :slight_smile:

Maybe I misunderstand the way Netlify forms work, the way I assumed is:

It POSTs the form data to the origin URL, or action URL. Then it redirects to the action URL, or I should get Netlify’s generic success or failure page.

Right now I’m getting 404 to the POST request:
Request URL:https://.com/feedback/
Request Method:POST
Remote Address:157.230.120.63:443
Status Code: 404
Version:HTTP/2
Referrer Policy:no-referrer-when-downgrade

And I get Netlify’s 404 page.

Screenshot_20200404_160151

Based on my assumption, I should get a 2XX response to the POST and be redirected to Netlify’s generic success page, and see the form submission under Forms on my Netlify dashboard. However I’m getting 404s all the way.

Also based on my assumption, if it would actually redirect to my 404 site or to a blank page of my app, if the POST was scuccessful, so I should only start worrying about the in app routing when I get to that point.

Is it possible that something got stuck on the Netlify side, or am I doing something wrong?

Thanks!

Ah, yeah, taking another look at your redirects, I see a few things that might be a problem:

  • Your _redirect for /feedback is set up as if Netlify is the server side of a REST API, but that’s not the case- with Netlify, there is no server at runtime, so you can go ahead and remove that rule.
  • Your third rule needs an index.html, so /* /index.html 200- that should fix your request url basically being empty

The way our forms work is that we get the request URL from your site. We parse the HTML and look for different attributes. If there’s an action there, we return the file listed at your action, which has already been built since that’s how Netlify and the Jamstack work- we generate your site assets and then deploy them to our CDN nodes. In your case, since your action=/feedback/success, we’ll return the file at yoursite.netlify.com/feedback/success , so that page has to be built by the time we say “now, show the success page!”

Do you want to make those changes to your _redirects file and let us know if that gets you closer?

1 Like

Thanks for the suggestions! I tried updating my _redirects, but so far, still no dice.

/api/*  https://<my-backend-domain>.com/api/:splat  200
/*  /index.html  200

Now it looks like this, and I’ve also added the success page to the prebuilt one in my Webpack config.

      plugins: [
        new PrerenderSPAPlugin(
          path.resolve(__dirname, 'dist'),
          ['/feedback', '/feedback/success'],
          {}
        )
     ]

I’ve also updated my Vue router, to make sure it’s able to handle the new route as well.

{
  path: '/feedback/',
  name: 'feedback',
  component: Feedback,
},
{
  path: '/feedback/success',
  name: 'feedbackSuccess',
  component: Feedback
},

Not much, it should at least render the same page as before, but I’m still getting 404. I’ve tried copying the request as curl from the browser’s network tab, but /feedback, /feedback/success, /feedback/index.html and /feedback/success/index.html return 404. I guess the index.html parts were quite unnecessary, but I was getting desperate :slight_smile:

Well, shoot, I’m almost out of ideas! Were you able to get the form POSTing and redirecting to Netlify’s default success page? Maybe a good next step would be to back up a bit, get that part working, and then we could debug the route to the custom success page once everything else was working?

You may also want to bring your code and site over to our Opentalk section https://community.netlify.com/c/opentalk/35 to see if anyone in there has ideas for you :face_with_monocle:

I managed to solve it after all. Let me leave the details here for later reference:

I extracted the Vue component’s html part into a simple feedback.html file and placed it in the public dir of the app. In the meantime, I updated my vue-router and served the Vue component on a different route. Submitting feedback.html worked like charm. I checked the network tab to see the difference between the two. They were mostly identical except for the data that was sent.

This is the one from the html:

await fetch("https://<my-domain>.netlify.app/feedback/result", {
    "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
    },
    "body": "form-name=feedback&bot-field=&feedback-text=test",
    "method": "POST",
});

and the one from the vue component:

await fetch("http://localhost:3000/feedback/result", {
    "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
    },
    "body": "bot-field=&feedback-text=test",
    "method": "POST"
});

As you can see, the form name is not included in the one posted by the Vue component. I’m not sure if this is an issue in Vue or it originated from the way I set up the component. However, I did not use JavaScript to post the data, only used good old form submit to do that.

After all, the solution was to use JavaScript, compile the URIEncoded data and POST it. Now it’s working and I could also get rid of the handmade feedback.html, as the PrerenderSPAPlugin takes care of it.

One thing I don’t understand: wouldn’t it be more semantically correct to send back 400 instead of 404 in this case? The status code mislead me as I thought there was a routing error, while it was malformed data that caused the issue.

1 Like

It might make more sense in this particular case, but our system won’t be able to return different status codes based on the data like that due to our network layout. So - good suggestion, but glad you won’t need it in the future :slight_smile: