Vue app with Netlify form throws error binding to events - vue.js

I am trying to hide/show a div if a form-input has a value. This works just fine with a regular form but if I implement it with netlify-forms I get the following error:
Unhandled promise rejection TypeError: "setting getter-only property "message""
<form name="newsletter" method="POST" data-netlify="true">
<input #input="email = $event.target.value" type="email" name="email">
<div :class="{'hidden': email === ''}">
<div data-netlify-recaptcha="true" />
</div>
</form>
I also tried #focus and #blur instead of #input but the error is always the same.
Without the data-netlify="true" it works as expected so I suspect it to have something to do with Netlify injecting something into the form.

In Netlify's guide on Netlify Forms + Vue, they say that the way SPAs are rendered can prevent Netlify's bots from HTML-editing the form to link it with their services.
By default Vue renders client side but the Netlify post processing bots expect HTML on site deploy. Any netlify form attribute tags included in a Vue app would only be inserted into the DOM client-side, rather than in the HTML and thereby runs the risk of being totally overlooked by the build bots.
To handle this, you have two options. You can either pre-render your application or add the netlify form to your static HTML file in your public folder.
So either pre-render your HTML (which gives an added speed and SEO bonus), or give netlify a static form to attach itself to, which you can then hide and replace with your nice Vue form on the client.

Related

Vue.js version 2 ignore customElement that extends form using is= syntax

Vue.js version 2 is changing the original syntax of my native customElement and because of the change the browser will not render it on the page.
Expected html on the DOM <form is="esm-justification-form"></form>
Actual html on the DOM <esm-justification-form></esm-justification-form>
In my vue template:
<div v-if="isEsm">
<form is="esm-justification-form"></form>
</div>
In my main app file, I have: Vue.config.ignoredElements = [/^esm-.*/]
In the browser where I register the component defineElement('esm-justification-form', justificationEle, 'form')
I've tested the regex expression outside of the app and it appears to be valid.
I could change from the 'is' syntax, but then 'this' would no longer be the form element. I have quite a few forms. I do not want to add extra code to select the form inside the component for events and such. There should be a way to prevent this.

Nuxt add GTM (noscript) to body tag on every page / route

I am trying to implement Google Tag Manager on a Nuxt app and am stuck on how to add the noscript tag to the app on every page / route inside the opening body tag. I tried creating a static script and adding the file through the nuxt config:
{ src: "/scripts/gtm.js", body: true }
which added the file to the body but was throwing errors due to the noscript tag and nested iframe from gtm. Not sure if there is a better way to inject the actual script directly inside the body
<!-- Google Tag Manager (noscript) -->
<noscript><iframe
src="https://www.googletagmanager.com/ns.html?id=GT
M-4BXKY65"
height="0" width="0"
style="display:none;visibility:hidden"></iframe></n
oscript>
<!-- End Google Tag Manager (noscript) -->
#Eike is correct there. Noscript is completely useless in 99.99% of GTM usage cases. It's used when a user has JS off, but unlike what you think, it won't make GTM work with no JS. In fact, only one tag can "fire" in that state and that would be a rarely used custom image tag. Most commonly used for firing pixels.
Yes, noscript implies an iframe and if your app doesn't support them, well then no noscript for you. Really, Nuxt is a front-end rendering framework. Why would you have anything in your <noscript> other than asking the user to enable JS in order to see the site...
The head property in your nuxt.config.js lets you define all the meta data and scripts that appear on each page. It looks like you can add a noscript section for what you need.
This applies to Nuxt v2.
I added the noscript GTM code through layouts/default.vue. Doing that inserts it into body, albeit not completely at the end (which is probably fine). I had to use v-html to avoid hydration mismatch errors ("The client-side rendered virtual DOM tree is not matching server-rendered content.").
<template>
<noscript v-html="iFrameCode" />
</template>
<script>
export default {
data() {
return {
iFrameCode: '<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XYXYXYX" height="0" width="0" style="display: none; visibility: hidden" />',
}
},
}
</script>
What confused me a bit when testing the implementations was the following:
When I had JavaScript on, this is what I saw in Chrome Dev Tools:
But when I tried turning JavaScript off, the code seemed to run fine:

How to setup a netlify form in Nuxt

When I navigate to a form using vue-router by adding a link with a <router-link> element, the form does not work. When I hit submit I get a 404 response.
However, if I navigate to it using an <a> tag (triggering a page reload) then it works perfectly.
I suspect that this has to do with the page rendering as a SPA and for some reason not loading an important part of the form for Netlify unless the form page is reloaded? Why is this happening and is there an elegant solution to the problem? I could just replace all links to forms with tags but I'm sure that there is a better solution, I just don't understand the problem well enough to find it.
For context, I am using Nuxt. The forms are recognized by Netlify on the backend and can accept submission with the tag link so that is not the problem.
Since you're using Nuxt, you probably should go SSG/full static with target: 'static' (hostable on Netlify-like platforms) or with target: 'server' (hostable on Heroku-like platforms) but at any point, you should have ssr: true (default value). When you do have this, the biggest part is done.
In Nuxt, you should use <nuxt-link> rather than <router-link>, it works exactly the same (takes the same params etc) but it's more specific to Nuxt and SSR/SSG compatible while <router-link> is not. More details here: https://nuxtjs.org/docs/2.x/features/nuxt-components#the-nuxtlink-component
So, with all of this it should already work great. If it's not, I will gladly help you spot the issue if you have a github repo.
An alternative solution can be to use some form without any SSR dependency like Formspree: https://formspree.io/ (works fine with any SPA)
It works great, really simple. But I'd rather invite you to make a proper SSR form since you're using Nuxt.
PS: use <a> tags only for external links aka the ones which do not start with your domain name, nothing else. A follow of this kind of link is like a hard refresh and should be avoided at all costs.
EDIT: how to deploy by cleaning the cache.
EDIT on how to achieve a working form:
<template>
<div>
<form
netlify
action="/"
method="POST"
name="Contact"
>
<input type="hidden" name="form-name" value="Contact" />
<!-- ... -->
</form>
</div>
</template>
As told in the docs:
[...] inject a hidden input named form-name [...] and the hidden form-name input’s value matches the name attribute of form
Working fine. Could add a honeypot to it to make it even more secure!

integration of ck editor in vue js

I am trying to integrate ckeditor with vue js in my application. Everything is working fine but when i click on submit button, all the data is saved in database and all fields are empty.
but in this case , i am not able to edit the ck-editor if i refresh or change the dom and again come to same page then working fine.
I think it needs to re-binding of ckeditor but I am not sure how we can do it.
I followed this link -> https://vuejsexamples.com/ckeditor-using-for-vue-js-2/
to integrate the ck-editor and also using js file of ckeditor on index page.
I assume that the Form which you are using is submitted by the browser - native html behaviour. To avoid that, the input field with type submit should look like (both #submit.prevent so as #click.prevent):
<form #submit.prevent="">
<input type="text" />
<input type="submit" value="ok" #click.prevent="" />
</form>

MVC helper inside a template

I am trying to use a kendo MVC helper inside a template (remote template file loaded like: http://docs.kendoui.com/howto/load-templates-external-files#remote-templates. I have a controller that sends to the client the generated markup)
My template file is something like:
<script id="my-pager-template" type="text/x-kendo-template">
My pager
#(Html.Kendo().ListView<Business.Data.MyPage>()
.Name("myPagerListView")
.TagName("div")
.ClientTemplateId("my-pager-item-template")
.DataSource(dataSource => dataSource.Read(read =>
read.Action("GetMyPages","Page")
)
).ToClientTemplate())
</script>
<script id="my-pager-item-template" type="text/x-kendo-template" >
<div class="k-button" data-pager-item-pageid="${PageID}" data-pager-item-pagename="${Name}">
<span>${ButtonText}</span>
</div>
</script>
But the generated markup is giving me an Uncaught SyntaxError: Unexpected token < in my browser console (chrome).
The markup generated by the helper is like this:
<div id="myPagerListView"></div>
<script>
jQuery(function(){jQuery("\#myPagerListView").kendoListView({"dataSource":{"transport":{"prefix":"","read":{"url":"/Page/GetMyPages"}},"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"type":"aspnetmvc-ajax","filter":[],"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"fields":{"PageID":{"type":"number"},"Name":{"type":"string"},"ButtonText":{"type":"string"}}}}},"template":kendo.template($('\#my-pager-item-template').html())});});
<\/script>
</script>
Can I use kendo helpers this way?
(In this post, it says that it can be used: Can I use Kendo MVC helpers inside templates?)
I got that message a lot of times, your code is fine, the problem comes retrieving the data, kendo deserialize what it recieves from read.Action("GetMyPages","Page"), you probably are retrieving an HTML page instead of a json, so it tries to serialize something like "<html ...." and here you got the error, just check the url on chrome to check if you recive an json
i mean check http://yourdomain.com/Pages/GetPages/ (or the routing according to your app), you probably get an HTML page
I had this exact issue also. I have come to realise (over the past 3 hours :( ) that this is because I was using ajax then the jquery html function to load the template file and that the error was happening with in jquery's function as it tried to parse than execute the template file which has been mangled for an unknown reason by kendo. (escaping that script tag and in my case inserting buttons in that space). Fortunatly when kendo Its self tries to use the template it does work.
To get around this problem I rendered the partial view directly on the page.
Hope this helps.