Creating trackable links even when a token includes “http://” or “https://”

Marketo's URL field type is a weird wee beastie. For one thing, it’s not long enough to fit all URLs (you can store decoded URLs to save space).

For another, although a URL value must begin with http:// or https:// when validated on a form (indeed, absolute URLs must have a protocol part[1]) including the protocol means a link to the corresponding {{lead.token}} won’t be tracked:

<a href="{{lead.token}}">

The latter quirk, of course, is also true of String and Textarea fields, as well as Text {{my.tokens}}. In order to be trackable, tokens used in hrefs must start with the hostname. Then you hard-code the protocol in the email asset or template, outside of the token:

<a href="https://{{lead.token}}">

This rule is easy to follow for {{my.tokens}} (as long as you knew it when building your templates).

But for custom lead fields, whether they’re of the named URL type or one of the Text types, it’s not so easy at all. You have information flowing in from various sources (API integrations, list uploads, etc.). And it’s natural for someone, if they weren’t explicitly warned, to put a full URL in a field that seems designed for... well, usable URLs.

Luckily, even if you’re cursed with full URLs, outputting your links using Velocity can solve the problem. Just use this little snippet, which clips out the protocol, then hard-codes it at the beginning of the href so Marketo will still track:

#set( $urlField = $lead.Website )
#set( $urlNoProto = $urlField.replaceAll("(?i)^https?://","") )
#if( $urlField.matches("(?i)^http://") )
<a href="http://${urlNoProto}">Go for it</a>
#else
<a href="https://${urlNoProto}">Go for it</a>
#end

Note the code is flexible enough to deal with full URLs and with protocol-less URLs, if you happen to have a mixture of values in the same field. It assumes the protocol is https:// if not included.

Notes

[1] The protocol doesn’t need to explicitly appear in a relative URL, be it via a scheme-relative URL like //example.com or a query-relative URL like ?query=string.

But a relative URL must resolve its missing components from somewhere to make the final URL. And there’s no such thing as a hostname-relative URL: <a href="www.example.com"> is a path-relative URL. If you put that link on the webpage https://www.example.net/my/page the final URL will be https://www.example.net/my/www.example.com, almost surely not what you want.