Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smhmic/d7c8b214931a662bae3c271091099914 to your computer and use it in GitHub Desktop.
Save smhmic/d7c8b214931a662bae3c271091099914 to your computer and use it in GitHub Desktop.
GTM AMP Container Proxy (for sharing GA Client ID with non-AMP pages)

This code is for serving an AMP GTM container from your own domain, so that the GA Client ID can be shared between your AMP pages and the rest of your site (enabling them to be tracked together in the same GA property).

Once the endpoint is deployed, you'll need to replace //www.googletagmanager.com/amp.json in the <amp-analytics> embed with the path to your endpoint (leaving the query parameters in place) within your AMP template's source code:

<amp-analytics 
  config="//www.googletagmanager.com/amp.json?id=GTM-XXXXX&gtm.url=SOURCE_URL" 
  data-credentials="include"></amp-analytics>

You can specifiy the cookie domain by appending &cookieDomain=YOURDOMAIN.COM to the endpoint URL.


This is based on Dan Wilkerson's script for Wordpress on Simo Ahava's blog. This has been modified to be vanilla PHP, with a couple fixes/enhancements, and minor improvements in performance and code simplicity.

<?php
// Callback for the GET request
function gtmAmpProxy_serve(){
//error_reporting(0);
// Get the hostname of the request origin, and parse it for the pure domain name.
$domain = explode( ':', $_SERVER['HTTP_HOST'] )[0];
if( !( $cookieDomain = @$_GET['cookieDomain'] ) ){
$cookieDomain = str_replace( 'www.', '', strtolower( $domain ) );
}
// Check if the browser already has the _ga cookie. If not, generate a new cookie.
$cid = $_COOKIE['_ga'];
if( !isset( $cid ) ){
$domainLength = count( explode( '.', $cookieDomain ) );
$cid = "GA1.{$domainLength}.".rand( 100000000, 999999999 ).'.'.time();
}
// Store the actual Client ID (last two numbers) of the _ga cookie value in the $cidNumber variable
$cidNumber = preg_replace( '/^GA.\.[^.]+\./', '', $cid );
// Fetch the actual GTM container, by passing the valid query parameters from the original request.
$container = file_get_contents( "https://www.googletagmanager.com/amp.json?$_SERVER[QUERY_STRING]" );
// Replace the &cid; parameter value with ${clientId}
$container = preg_replace( '/(&cid=)[^&]+/', '${1}${clientId}', $container );
// Add the clientId to the "vars" object in the container JSON.
$container = json_decode( $container );
$container->vars->clientId = $cidNumber;
// Build a new HTTP response from the modified configuration file.
$response = json_encode( $container );
// Clear output that could create an invalid response (i.e. PHP warnings).
@ob_clean();
// Clear any existing response headers.
header_remove();
// Add the required headers (Set-Cookie, most importantly) to the Request
http_response_code( 200 );
header( "Set-Cookie: _ga={$cid}; Domain={$cookieDomain}; Path=/; Secure; SameSite=None; "
."Expires=".date( 'D, j F Y H:i:s', time()+60*60*24*365*2)." GMT;" );
header( 'Access-Control-Allow-Origin: https://cdn.ampproject.org' );
header( "AMP-Access-Control-Allow-Source-Origin: https://{$domain}" );
header( 'Access-Control-Expose-Headers: AMP-Access-Control-Allow-Source-Origin' );
header( 'Content-Type: application/json; charset=utf-8' );
// Return the HTTP response.
echo $response;
exit();
}
gtmAmpProxy_serve();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment