Reputation: 191
I am implementing GTM on a website. Website has 400+ pages on which GTM script has to be placed. Is there any way to inject GTM script on every page right after the body tag? Website uses mixed technology, some pages are in ASP.NET 4.0 and some in MVC 4.0. Below is the sample script to be added:
<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-#####"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<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=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-#####');</script>
<!-- End Google Tag Manager -->
Upvotes: 0
Views: 2316
Reputation: 3154
For the MVC pages uou should place your script in the default layout file of your web application and then you set the layout for every view in the _ViewStart.cshtml file.
For your Web Form pages you can do the same with a master page.
Upvotes: 2
Reputation: 3154
Based on the edit you did in your question, you need an HTTP Module that will modify the code that is generated injecting your script.
First you need to create a class that derive from Stream, that will wrap you original Stream from Response.Filter.
public class GtmStream : Stream
{
private static string gtmScript = @"<!-- Google Tag Manager -->...";
private Stream _base;
public GtmStream(Stream stream)
{
_base = stream;
}
public override void Flush()
{
_base.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _base.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
var editedBuffer = GetByteArrayWithGtmScriptInjected(buffer);
_base.Write(editedBuffer, offset, editedBuffer.Length);
}
public byte[] GetByteArrayWithGtmScriptInjected(byte[] buffer)
{
var stringValue = System.Text.Encoding.UTF8.GetString(buffer);
if (!string.IsNullOrWhiteSpace(stringValue))
{
var position = stringValue.IndexOf("</body>");
if (position != -1)
{
stringValue = stringValue.Insert(position + 7, gtmScript);
}
}
return System.Text.Encoding.UTF8.GetBytes(stringValue.ToCharArray());
}
public override bool CanRead
{
get { throw new NotImplementedException(); }
}
public override bool CanSeek
{
get { throw new NotImplementedException(); }
}
public override bool CanWrite
{
get { throw new NotImplementedException(); }
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
Every time the method Write will be called, the Stream will check if it contains the tag and if it exists it will inject the script code just after it.
Then it will return the new byte array and call the Write method on the base Stream.
To plug it into your web application you need to create an HTTP Module, as follows:
public class GtmScriptModule : IHttpModule
{
private GtmStream gtmStream;
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
gtmStream = new GtmStream(application.Context.Response.Filter);
application.Context.Response.Filter = gtmStream;
}
public void Dispose()
{
}
}
This will simply set the Response.Filter to your custom Stream.
Finally you need to plug your HTTP Module in your web application:
<system.web>
...
<httpModules>
<add name="GtmScriptModule" type="TestMvcApplication.Modules.GtmScriptModule, TestMvcApplication" />
</httpModules>
</system.web>
Upvotes: 4
Reputation: 6917
try creating an HTTP Module that will run on every request, check if the request is for a page, if so send back your javascript block
https://msdn.microsoft.com/en-us/library/vstudio/ms227673(v=vs.100).aspx
Upvotes: 1