A simple way to output query param values in the page body

💡
This code does not work in any version of Internet Explorer, as it relies on URLSeachParams and Custom Elements v1.

An earlier post showed how to append form field values to the Thank You URL’s query string, but admittedly hand-waved how you would output query params on that next page.

Indeed, you might not want to output query values at all, just process them in JS. And if you do want to output, a full-fledged JS template engine (I’m partial to SquirrellyJS) is best.

But maybe you don’t want to deal with the learning curve of templates. You just want the equivalent of a {{lead.token}} to pop into any HTML page (think of it as a {{query.token}}).

Custom elements — which I was skeptical about for an embarrassingly long time — are a simple solution.

One cool thing about CEs is that they’re “alive” from a JS standpoint, firing callbacks when they’re connected to the document[1], no matter whether they were in the original HTML markup or added later via JS (or added via a script that was itself injected by another script, etc.).

So let’s set up a CE that’s designed to populate its inner text with the value of a query param. Put this in the <head>:

<script>
  /**
   * Quick transplant of query param values to document body
   * @author Sanford Whiteman, TEKNKL
   */
  {
    let currentQuery = new URLSearchParams(document.location.search);

    class QueryParamOutput extends HTMLElement {
      constructor() { 
        super(); 
      }
      connectedCallback() { 
        let paramName = this.getAttribute("name")
        this.textContent = currentQuery.get(paramName); 
      }
    }

    customElements.define("output-query-param", QueryParamOutput);
  }
</script>
Define the Custom Element once.

Then you can insert an <output-query-param> anywhere — on any page, Marketo or non-Marketo — and it’ll fill itself in:

Hello, <output-query-param name="FirstName"></output-query-param> <output-query-param name="LastName"></output-query-param>
Use the Custom Element anywhere.

Of course, Custom Elements can do much bigger things, but even within this narrow requirement, they’re easier than the alternative. (The alternative would be doing full-text searches for some kind of replacement expression, %%query.token%% or {{query.token}} or [[query.token]], remembering to detect dynamically injected content. Not easy!)

Notes

[1] You can simulate this with regular elements using DOM Mutation Observers, but it’s an additional level of indirection.