Combining Progressive Profiling with (the equivalent of) Known Visitor HTML

Progressive Profiling (ProgPro) and Known Visitor HTML (KV HTML) are both handy features. But they can’t be used at the same time: when KV HTML is enabled, it takes precedence.

And this makes sense.

KV HTML means “Hide all form fields when the pageview[1] is associated with a known lead. Just show a button and a little custom text.”

ProgPro means “Show a set of empty fields to be filled in by the lead, and optionally some always-on fields.”

You can’t both “hide all fields” and “show some fields” simultaneously, so “hide all fields” wins out.

But what if you only want to use ProgPro until all fields are filled, then switch modes to KV HTML (i.e. just display a Download button like you would with KV HTML)?

So the form might start like this:

Then look like this if a couple of ProgPro fields are still empty:

And like this when the whole ProgPro block is filled:

This is easy to do with a tiny bit o’ JS & CSS. You can’t do it with native KV HTML, though, so turn that off while leaving ProgPro on:

Then put a KV HTML-like block in a Rich Text area at the top of the form, and put all the other user-visible fields inside the ProgPro block:

(I included a Hidden field filled from a query param to show those should be outside the ProgPro block as well.)

Now, some CSS to hide the topmost Rich Text area by default:

.mktoForm > .mktoFormRow:first-of-type {
    display: none;
.mktoForm[data-kv-equiv="true"] > .mktoFormRow:first-of-type {
    display: block;

And then JS to detect whether there are any fields shown to the user:

   let formEl = form.getFormElem()[0],
       visibleInputs = formEl.querySelectorAll("input:not([type='hidden']),select,textarea"),
       submitButton = formEl.querySelector(".mktoButton");
   if(visibleInputs.length == 0) {
      submitButton.textContent = "Download";

visibleInputs collects all the non-Hidden fields (Text, Date, Phone, Checkbox, Select, Textarea, etc.).

If its length is 0, that means there aren’t any fields shown to the user. In that case we add a CSS class to the form element. That’s picked up by the stylesheet to show the Known-Visitor-HTML-equivalent Rich Text. We also tweak the button text just for completeness.

On non-Marketo LPs, this is missing one feature offered by native KV HTML

When you use the form embed code on non-Marketo pages, you’re allowed to use {{lead.First Name}} and {{lead.Last Name}} tokens — but only those 2 tokens — inside the KV HTML section. (Yes, this is the sole exception to the rule that field values are not natively available cross-domain.)

Since the solution here uses a standard Rich Text field instead of KV HTML™, you can’t put tokens in it unless you’re on a Marketo LP.

But you could use my Cross-Domain Pre-Fill JS to display lead values in the emulated KV HTML. (And not just First Name and Last Name, any fields you want!)


[1] I didn’t say “... when the Munchkin cookie is associated with a known lead” because there’s a case that doesn’t involve Munchkin: clicking a tracked email link. “Pageview” is meant to cover both cases.