Today I learned that there's a gotcha when injecting script into pages using IIS's UrlRewrite: JavaScript scripts with braces.
Braces have a purpose in rewrite rules, to introduce those things captured in the match clause. Notice in the following outbound rule, that the text captured by the regular expression in the match pattern
is reinserted in the action
.
<rule name="Inject GTM After /TITLE" preCondition="ResponseIsHtml1" enabled="true" stopProcessing="true">
<match filterByTags="None" pattern="</title>" />
<action type="Rewrite" value="{R:0}<!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXX" height="0" width="0" style='display:none;visibility:hidden'></iframe></noscript> <!-- End Google Tag Manager (noscript) -->" />
</rule>
So there we were trying to embed a GTM script into a page via a rewrite rule, viz
<rule name="Inject GTM After /TITLE" preCondition="ResponseIsHtml1" enabled="true">
<match filterByTags="None" pattern="</title>" />
<action type="Rewrite" value="{R:0}<!-- Google Tag Manager --> <script>(function(w,d,s,l,i) { w[l]=w[l]||[];w[l].push( { 'gtm.start': new Date().getTime(),event:'gtm.js' } );var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); } )(window,document,'script','dataLayer','GTM-XXXX');</script> <!-- End Google Tag Manager -->" />
</rule>
That looked like it would work but it does NOT as the JavaScript contains {
and IIS's UrlRewrite tool immediately complains with a yellow box reading The rewrite provider " w[l]=w[l]||[];w[l].push( { 'gtm.start'" does not exist
(note that it terminates at the : which would separate the usual R or C from the numeric qualifier.)
We tried swapping {
with {
but that doesn't work well, giving us the following in the generated web page:
<!DOCTYPE HTML>
<html lang="en">
<head><title>The Page</title><!-- Google Tag Manager --> <script>(function(w,d,s,l,i) { w[l]=w[l]||[];w[l].push( { 'gtm.start': new Date().getTime(),event:'gtm.js' } );var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); } )(window,document,'script','dataLayer','GTM-XXXX');</script> <!-- End Google Tag Manager -->
<meta charset="UTF-8"/>
Naturally, the browser's JavaScript interpreter complains about bad code.
What we finally ended up doing was to create a js file in another of our websites and then embed a reference to it in the rule, viz
<rule name="Inject GTM After /TITLE" preCondition="ResponseIsHtml1" enabled="true" stopProcessing="true">
<match filterByTags="None" pattern="</title>" />
<action type="Rewrite" value="{R:0}<!-- Google Tag Manager --> <script type="text/javascript" src="https://sub.domain.com.au/js/GTM-XXXX.js"></script> <!-- End Google Tag Manager -->" />
</rule>
Maybe this is the better thing to do. It'll do for now.
Top comments (0)