Same-page Thank You text with Marketo Forms

Marketo Forms 2.0 “Stay on page” behavior (the default) can cause a few subtle problems — because it doesn't actually stay on the page hosting the form. Rather, it refreshes the same page.

Well, almost the same page: it keeps the initial URL, but also adds the aliId= parameter to the query string. The undocumented refresh-and-append can cause problems under some circumstances.

Small problems that add up to trouble

As Marketo Champ DS pointed out on the Community, if you have a Smart Campaign using a strict Referrer match on the next page (is constraint), you'll be in for a surprise since Marketo adds a query param without your explicit consent. Personally, I don't think you should be doing an end-to-end is comparison anyway, since you can't control search engines adding other stuff to your URL (in a good way). But that's not the only problem with the default behavior.

An undeniable additional problem is that, well, the entire page refreshes from the server. That's unnecessary load and kind of a strange UX these days. It'll appear that the lead viewed the page twice in your analytics, if you're counting such things. And unless you're using Known Lead HTML or PreFill, the lead just sees the same form again with empty fields, and no confirmation that the form submitted correctly.

Another more technical problem is that it always GETs the new page, even if the page initially loaded via POST. This could potentially cause a different page to render, or an error page, if your server happens to, for example, expect search terms to be POSTed to the page hosting the form. (This will never be a problem on Marketo-hosted LPs, to be sure, but could happen with embedded forms on your own CMS-driven site.)

Staying on the page, for real

With all the above cons, it's clear that the built-in “Stay on page” option is best avoided. So how do we truly keep people on the same page after filling in the form, with no page reload nor change to the location bar? At its simplest, like so:

    return false;

Short and simple: we add an onSuccess listener that returns boolean false. That one line keeps us on the same page. But we're not doing anything to change the page content, so it ends up looking like this, kind of frozen in time with the Please Wait still in progress (even though actually the form submitted sucessfully):


So clearly we need to do more than just return false. We need to also replace the contents of the form with something confirmation-y like this:


Replacing form content with your Thank You text

There are a couple of recipes out there that basically work, but they all involve (to me) clumsy stuff like including a <DIV> with Thank You text in the page itself, above or below the <FORM> element, and then removing the form element and unhiding the container. Or setting the form's innerHTML to some text that's hard-coded in the whenReady JavaScript.

Like I said, the above both work as far as the end-user knows, but I like to keep form settings within the form itself, so you can update them easily using Form Editor.

So here's my 2-step (optionally, 3-step) recipe for easily maintainable Thank You text.

[1] In Form Editor » Settings » Thank You page, set up your Thank You text block(s) by using the External URL option. But you won't need to use a real URL: we are entering the Thank You text as the #hash of a placeholder URL. So you can start with any hostname you want, like or The text goes after the #, like so: you for your submission! You'll hear from us soon.

Here's a screenshot (though the short textboxes in Form Editor won't show the full contents):


See how you're still able to use the Add Choice function to switch the Thank You text based on form values... pretty cool, eh? And ==you can also use {{my.tokens}} to store Thank You text snippets == if you're on a Marketo LP.

[2] Include this onSuccess JavaScript function in your main document or in a Rich Text area. You never need to edit anything within this code (that's the idea — it reads your site-specific text from the form itself):

  form.onSuccess(function(vals, thankYouURL) {
    var formEl = form.getFormElem()[0],
        thankYouLoc = document.createElement('A'),
        thankYouContainer = formEl.querySelector('#thankYouContent') || document.createElement('DIV'),

    thankYouHTML = decodeURIComponent((thankYouLoc.href = thankYouURL, thankYouLoc).hash.substring(1));
    formEl.innerHTML = (thankYouContainer.innerHTML = thankYouHTML, thankYouContainer).outerHTML;

    return false;

With this code in place, the normal redirection to the thankYouURL will be skipped, and instead the #hash value gets parsed out of the thankYouURL and injected in place of the form contents.

[3] (Fully optional) Add a rich-text area to the form, and inside it add a container <DIV id="thankYouContent">. You only need to do this if you want to apply special styling to the Thank You text. If you just want plain text to replace the contents of the form, then you can skip it. If you do use this feature, you also want to hide the container by default, so I've also included hide/show styles to add to your Custom CSS:


Note again that you won't be editing this rich-text area. It's just a placeholder inside which the Thank You text (set in [1]) is placed so you can style it further.

Other thoughts

The logic above could be refactored to use the query string instead of the hash; that's just a personal choice. In either case the Thank You URL isn't being used verbatim, but rather as a string that happens to be structured like a URL to pass Marketo UI validation (which is why you need to start it with

Even if you don't have {{my.tokens}}, you could expand the same approach to use Thank You snippets that are themselves stored in a rich-text area, then use short references to those snippets like{{my.thankYou}}. Or various other permutations as well.

Leave questions in the comments!