Netlify Forms: Invalid HTML of the hidden input element

According to (docs/form-handling/#ajax-form-submissions) you add a hidden input element. A valid HTMLInputElement has no closing tag and is void, i.e. it’s never closed. However, for some reason inside my Netlify App using Netlify Forms when inserted the hidden HTMLInputElement looks like this:

<input type='hidden' name='form-name' value='contact-form' />

I’ve marked the above code snippet as XHTML, because this ^ is not valid HTML:

In HTML, the <input> tag has no end tag.
In XHTML, the <input> tag must be properly closed, like this <input />.

It’s causing an unexplicable error in Nuxt (Vue):
DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.

Because it’s invalid Chrome tries to guess what’s happening and does this:

It nests a text node and another HTMLInputElement inside of an HTMLInputElement, but since an Input Element is void it cannot have anything inside it and Vue does not know what’s going on at this point!

It’s very frustrating, because everything works fine on my development machine and the reason something goes wrong is something I cannot control. It’s been a major source of frustration in my life for the last few hours :dagger:

(this is a copy of netlify-cms issue #2396 I have misplaced on the Netlify-CMS team, I’ve also sent a support ticket )

Hey @jcubed,

Thanks for pinging us on this. I tried to replicate your issue and I think the issue as you pointed out may have to do with invalid HTML. This issue on the Nuxt repo explain this a little more in depth.

It’s hard to tell where exactly in your application this is happening, but if it helps, I’ve created an example Nuxt app that includes a Netlify form for reference. Let me know if you still run into issues!

  • Divya

Hi, just wanted to chime in and say that you’re correct that Netlify forms shouldn’t be closing that input. I got an issue filed on that so we can get it fixed. @divya can speak more to the vue side of this, but if you can provide more information, including a code example, I’d love to see what’s happening since I haven’t seen others experience similar errors with netlify forms and nuxt.js

Thanks for getting back to me @futuregerald and @divya!

This issue seems weird if it’s only happening to me. I’ve recently made my project repo public. I have tested Netlify Forms on a feature branch and just left it there hanging once I couldn’t get it to work.

Here’s the exact place the forms are used:

Here’s the fetch request @submit.prevent event handler of the form:

I don’t know what else could cause it since it’s working fine on my computer when I run both npm run dev and npm run generate but the issue happens when I put the site on Netlify. But then again if it happens only to me… weird.

Now I noticed the only thing different in my code and divya’s is that I wrap my inputs in labels, i.e.:

<label for="name">
    Your name:
    <input name="name">

While divya does this:

<label for="name">Your name:</label>
<input name="name">

According to W3Schools it’s valid:

Tip: A label can be bound to an element either by using the "for" attribute, or by placing the element inside the <label> element.

I guess my fors in labels are unnecessary ¯\(ツ)/¯. This is the syntax in your docs also (/docs/form-handling/). Maybe this is the culprit and the reason why it would be rare?

Hmm, hard for me to say as a total Vue newbie, but since you have a working setup already handy, maybe you could try without just to see if that helps and let us know?

Sure thing, chief.

So I did and the issue is gone!
Here’s the newly generated HTML that doesn’t produce errors:

<form name='contact-form' data-netlify-recaptcha='true' data-v-03c002d6 method='post'><input type='hidden' name='form-name' value='contact-form' /><label for="name" data-v-03c002d6>
				Twoje imię:
			</label> <input name="name" data-v-03c002d6> <label for="e-mail" data-v-03c002d6>
				Twój e-mail:
			</label> <input name="e-mail" data-v-03c002d6> <label for="body" data-v-03c002d6>
				Twoja wiadomość:
			</label> <textarea name="body" data-v-03c002d6></textarea> <label for="nie-wpisuj-tego" data-v-03c002d6>
				Nie wpisuj tego:
			</label> <input name="nie-wpisuj-tego" data-v-03c002d6> <div data-v-03c002d6>

Here’s the one producing the problem:

<form name='contact-form' data-netlify-recaptcha='true' data-v-3a49ccba method='post'><input type='hidden' name='form-name' value='contact-form' /><label for="name" data-v-3a49ccba>
				Twoje imię:
				<input name="name" data-v-3a49ccba></label> <label for="e-mail" data-v-3a49ccba>
				Twój e-mail:
				<input name="e-mail" data-v-3a49ccba></label> <label for="body" data-v-3a49ccba>
				Twoja wiadomość:
				<textarea name="body" data-v-3a49ccba></textarea></label> <label for="nie-wpisuj-tego" data-v-3a49ccba>
				Nie wpisuj tego:
				<input name="nie-wpisuj-tego" data-v-3a49ccba></label> 

Here’s the comparison of how it gets interpreted in Chrome (I couldn’t get two images in here so I had to improvise):

There’s still the uncertainty of whether the “Twoje imię” string will be shown in the new one since that text is contained inside an input and that’s not allowed (after interpreting in Chrome/Vue), but it shows up. I got the HTML snippets from view-source, but the images are from Chrome DevTools, so I’m not sure if it’s Chrome that makes the resulting HTML different from the source or maybe Vue behind the scenes trying to make sense of it all.

Seems like closing the input combined with the labels somehow causes the problem. Well, at least I got it working! Thanks.