diff --git a/analytical/templatetags/analytical.py b/analytical/templatetags/analytical.py
index f74684e..72b3234 100644
--- a/analytical/templatetags/analytical.py
+++ b/analytical/templatetags/analytical.py
@@ -24,6 +24,7 @@
'analytical.gauges',
'analytical.google_analytics',
'analytical.google_analytics_js',
+ 'analytical.google_gtag_js',
'analytical.gosquared',
'analytical.hotjar',
'analytical.hubspot',
diff --git a/analytical/templatetags/google_gtag_js.py b/analytical/templatetags/google_gtag_js.py
new file mode 100644
index 0000000..a8c31f5
--- /dev/null
+++ b/analytical/templatetags/google_gtag_js.py
@@ -0,0 +1,129 @@
+"""
+Google Analytics template tags and filters, using the new gtag.js library.
+
+gtag.js documentation found at: https://developers.google.com/analytics/devguides/collection/gtagjs/
+API reference at: https://developers.google.com/gtagjs/reference/api
+"""
+
+from __future__ import absolute_import
+
+import re
+import json
+from django.conf import settings
+from django.template import Library, Node, TemplateSyntaxError
+
+from analytical.utils import (
+ disable_html,
+ get_required_setting,
+ is_internal_ip,
+)
+
+GA_MEASUREMENT_ID_RE = re.compile(r'[a-zA-Z\d_\-]+')
+
+SETUP_CODE = """
+
+
+"""
+
+CUSTOM_SET_KV_CODE = "gtag('set', '{key}', {value_json});"
+CUSTOM_SET_DATA_CODE = "gtag('set', {value_json});"
+
+# You are allowed to config more than one GA_MEASUREMENT_ID on a page.
+# This could be used, but for now is not.
+CUSTOM_CONFIG_CODE = "gtag('config', '{property_id}', {config_parameters_json});"
+
+register = Library()
+
+
+@register.tag
+def google_gtag_js(parser, token):
+ """
+ Google Analytics Global Site Tag tracking template tag.
+
+ Renders Javascript code to track page visits. You must supply
+ your website property ID (as a string) in the
+ ``GOOGLE_GTAG_JS_PROPERTY_ID`` setting.
+ """
+ bits = token.split_contents()
+ if len(bits) > 1:
+ raise TemplateSyntaxError("'%s' takes no arguments" % bits[0])
+ return GoogleGTagJsNode()
+
+
+class GoogleGTagJsNode(Node):
+ def __init__(self):
+ self.property_id = get_required_setting(
+ 'GOOGLE_GTAG_JS_PROPERTY_ID', GA_MEASUREMENT_ID_RE,
+ "must be a string like a slug")
+
+ def render(self, context):
+ config_parameters = self._get_config_parameters(context)
+ config_parameters_json = self._to_json(config_parameters)
+
+ set_commands = self._get_set_commands(context)
+
+ html = SETUP_CODE.format(
+ property_id=self.property_id,
+ config_parameters_json=config_parameters_json,
+ set_commands=" ".join(set_commands),
+ )
+ if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
+ html = disable_html(html, 'Google Analytics')
+ return html
+
+ def _get_config_parameters(self, context):
+ config_data = getattr(
+ settings, 'GOOGLE_GTAG_JS_DEFAULT_CONFIG', {},
+ )
+
+ config_data.update(context.get('google_gtag_js_config_data', {}))
+
+ return config_data
+
+ def _to_json(self, data, default="{}"):
+ try:
+ return json.dumps(data)
+ except ValueError:
+ return default
+ except TypeError:
+ return default
+
+ def _get_set_commands(self, context):
+ commands = []
+
+ if 'google_gtag_js_set_data' in context:
+ try:
+ commands.append(CUSTOM_SET_DATA_CODE.format(
+ value_json=json.dumps(context['google_gtag_js_set_data']),
+ ))
+ except ValueError:
+ pass
+
+ values = (
+ context.get('google_gtag_js_set%s' % i) for i in range(1, 6)
+ )
+ params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
+
+ for _, var in params:
+ key_name = var[0]
+ value = var[1]
+ try:
+ value_json = json.dumps(value)
+ except ValueError:
+ value_json = json.dumps(str(value))
+ commands.append(CUSTOM_SET_KV_CODE.format(
+ key=key_name,
+ value_json=value_json,
+ ))
+ return commands
+
+
+def contribute_to_analytical(add_node):
+ GoogleGTagJsNode() # ensure properly configured
+ add_node('head_top', GoogleGTagJsNode)
diff --git a/analytical/tests/test_tag_google_gtag_js.py b/analytical/tests/test_tag_google_gtag_js.py
new file mode 100644
index 0000000..1a80d26
--- /dev/null
+++ b/analytical/tests/test_tag_google_gtag_js.py
@@ -0,0 +1,107 @@
+"""
+Tests for the Google Analytics template tags and filters, using the new analytics.js library.
+"""
+
+from django.http import HttpRequest
+from django.template import Context
+from django.test.utils import override_settings
+
+from analytical.templatetags.google_gtag_js import GoogleGTagJsNode
+from analytical.tests.utils import TagTestCase
+from analytical.utils import AnalyticalException
+
+
+@override_settings(GOOGLE_GTAG_JS_PROPERTY_ID='UA-123456-7')
+class GoogleGTagJsTagTestCase(TagTestCase):
+ """
+ Tests for the ``google_gtag_js`` template tag.
+ """
+
+ def test_tag(self):
+ r = self.render_tag('google_gtag_js', 'google_gtag_js')
+ self.assertTrue("""
+
+