GTM Server-Side ships with built-in tags for GA4, Google Ads, and Meta — but what if you need to send data to your CRM, a data warehouse, a Slack webhook, or a custom analytics platform? Server-side tag templates let you build your own tag that receives event data and POSTs it anywhere. This guide walks through building a functional custom tag template from scratch.

Tag Template Anatomy

A GTM SS tag template has four parts: Fields (the configuration UI), Permissions (which external domains the tag can call), Code (the sandboxed JavaScript that runs when the tag fires), and Tests (optional unit tests). Templates use sandboxed JavaScript — not full Node.js — with specific APIs instead of standard modules.

Available APIs in Sandboxed JS

  • sendHttpRequest(url, options) — makes HTTP requests to external APIs
  • getAllEventData() — gets the full event payload from the client
  • getEventData(key) — gets a specific event field
  • logToConsole() — writes to GTM SS debug console
  • sha256(value) — built-in hashing for PII

Example: Webhook Tag That Posts to Slack

const sendHttpRequest = require('sendHttpRequest');
const getAllEventData = require('getAllEventData');
const JSON = require('JSON');
const logToConsole = require('logToConsole');

const webhookUrl = data.webhookUrl;
const eventData = getAllEventData();

const payload = {
  text: 'New conversion: ' + eventData.event_name,
  blocks: [{
    type: 'section',
    text: {
      type: 'mrkdwn',
      text: '*Event:* ' + eventData.event_name +
            '
*Value:* $' + (eventData.value || 0) +
            '
*Page:* ' + (eventData.page_location || 'unknown')
    }
  }]
};

sendHttpRequest(webhookUrl, {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify(payload)
}, function(statusCode, headers, body) {
  if (statusCode >= 200 && statusCode < 300) {
    logToConsole('Slack notification sent');
    data.gtmOnSuccess();
  } else {
    logToConsole('Slack error: ' + statusCode);
    data.gtmOnFailure();
  }
});
GTM Server-Side Tag Templates: Build a Custom Tag for Any API

Setting Permissions

In the template editor, Permissions tab → HTTP Requests → add the domains your tag will call. For Slack: hooks.slack.com. For a custom API: api.yourcompany.com. Without explicit permission, sendHttpRequest is blocked even if the code runs — this is a common “tag fires but nothing happens” mystery.

Template Fields Configuration

  • Field name: webhookUrl, Type: Text, Display name: “Slack Webhook URL”
  • Field name: eventFilter, Type: Text, Display name: “Only fire for events (comma-separated)”
  • Add validation: webhookUrl must start with “https://hooks.slack.com”

Testing Your Template

Use GTM SS Preview mode: send a test event via the debug URL, then check the Preview panel to see if your tag fired, what response it received, and whether gtmOnSuccess() or gtmOnFailure() was called. The Preview panel shows console logs from logToConsole() in real time.

Related: GTM Server-Side Preview Mode, Server-Side Cookie Duration.

Guide

Leave a Comment