or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Gatsby Plugin Google Tag Manager

Gatsby plugin that provides seamless integration with Google Tag Manager (GTM) for Gatsby websites, enabling comprehensive analytics and tag management capabilities. The plugin automatically injects the required GTM scripts into the HTML head and body, supports both production and development environments with configurable inclusion, and provides advanced features like custom data layer configuration, environment-specific GTM settings, and Core Web Vitals tracking.

Package Information

  • Package Name: gatsby-plugin-google-tagmanager
  • Package Type: npm
  • Language: JavaScript/React
  • Installation: npm install gatsby-plugin-google-tagmanager

Core Imports

This is a Gatsby plugin - it's not imported directly. Instead, it's configured in your gatsby-config.js file:

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: "gatsby-plugin-google-tagmanager",
      options: {
        id: "YOUR_GOOGLE_TAGMANAGER_ID",
        // Additional options...
      },
    },
  ],
};

Basic Usage

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: "gatsby-plugin-google-tagmanager",
      options: {
        id: "GTM-XXXXXXX",
        includeInDevelopment: false,
        defaultDataLayer: { platform: "gatsby" },
        enableWebVitalsTracking: true,
      },
    },
  ],
};

Architecture

The plugin integrates with Gatsby's lifecycle through several hooks:

  • onPreInit: Processes and validates plugin configuration options
  • onRenderBody: Injects GTM tracking scripts during server-side rendering
  • onRouteUpdate: Handles client-side route change tracking
  • onInitialClientRender: Sets up Web Vitals performance monitoring

The plugin operates by injecting Google Tag Manager's JavaScript snippet into the HTML head, optionally setting up a custom data layer, and providing automatic route change tracking for single-page application navigation.

Capabilities

Plugin Configuration

Configure the plugin through the Gatsby plugin options system with comprehensive validation.

interface PluginOptions {
  /** Google Tag Manager ID that can be found in your Tag Manager dashboard */
  id?: string;
  /** Include Google Tag Manager when running in development mode (default: false) */
  includeInDevelopment?: boolean;
  /** Data layer to be set before Google Tag Manager is loaded. Should be an object or a function (default: null) */
  defaultDataLayer?: object | (() => object) | null;
  /** Google Tag Manager environment auth string (default: undefined) */
  gtmAuth?: string;
  /** Google Tag Manager environment preview name (default: undefined) */
  gtmPreview?: string;
  /** Data layer name (default: "dataLayer") */
  dataLayerName?: string;
  /** Name of the event that is triggered on every Gatsby route change (default: "gatsby-route-change") */
  routeChangeEventName?: string;
  /** Enable Core Web Vitals tracking (default: false) */
  enableWebVitalsTracking?: boolean;
  /** The origin where GTM is hosted (default: "https://www.googletagmanager.com") */
  selfHostedOrigin?: string;
  /** The path where GTM is hosted (default: "gtm.js") */
  selfHostedPath?: string;
}

Configuration Examples:

// Basic configuration
{
  resolve: "gatsby-plugin-google-tagmanager",
  options: {
    id: "GTM-XXXXXXX",
  },
}

// Advanced configuration with custom data layer
{
  resolve: "gatsby-plugin-google-tagmanager",
  options: {
    id: "GTM-XXXXXXX",
    includeInDevelopment: true,
    defaultDataLayer: { platform: "gatsby", version: "5.0" },
    dataLayerName: "customDataLayer",
    routeChangeEventName: "page-view",
    enableWebVitalsTracking: true,
  },
}

// Dynamic data layer with function
{
  resolve: "gatsby-plugin-google-tagmanager",
  options: {
    id: "GTM-XXXXXXX",
    defaultDataLayer: function () {
      return {
        pageType: window.pageType,
        userAgent: window.navigator.userAgent,
      };
    },
  },
}

// Self-hosted GTM configuration
{
  resolve: "gatsby-plugin-google-tagmanager",
  options: {
    id: "GTM-XXXXXXX",
    selfHostedOrigin: "https://your-domain.com",
    selfHostedPath: "custom-gtm.js",
  },
}

// GTM environment configuration
{
  resolve: "gatsby-plugin-google-tagmanager",
  options: {
    id: "GTM-XXXXXXX",
    gtmAuth: "YOUR_AUTH_STRING",
    gtmPreview: "env-1",
  },
}

Route Change Tracking

Automatic tracking of route changes in your Gatsby application through the browser API.

/**
 * Gatsby browser lifecycle hook that fires route change events in GTM data layer
 * Automatically called by Gatsby on route transitions
 * @param _ - Gatsby API object (unused)
 * @param pluginOptions - Plugin configuration options
 */
function onRouteUpdate(_: any, pluginOptions: PluginOptions): void;

The plugin automatically fires a gatsby-route-change event (or custom event name from routeChangeEventName option) to the GTM data layer whenever users navigate between pages. This enables tracking of single-page application navigation in Google Tag Manager. The event is fired with a 50ms timeout to ensure the page title has been properly updated.

Data Layer Event Structure:

// Default event fired on route changes
{
  event: "gatsby-route-change"  // or custom routeChangeEventName
}

Server-Side Rendering Integration

Automatic injection of GTM tracking code during the build process.

/**
 * Gatsby SSR lifecycle hook that injects GTM scripts into HTML
 * Automatically called by Gatsby during build/SSR
 * @param gatsbyApi - Gatsby SSR API object with setHeadComponents and setPreBodyComponents
 * @param pluginOptions - Plugin configuration options
 */
function onRenderBody(
  gatsbyApi: {
    setHeadComponents: (components: React.ReactNode[]) => void;
    setPreBodyComponents: (components: React.ReactNode[]) => void;
    reporter: {
      panic: (message: string) => never;
    };
  },
  pluginOptions: PluginOptions
): void;

The plugin automatically:

  • Injects the GTM JavaScript snippet into the HTML <head> using the standard Google Tag Manager template
  • Sets up the data layer with any configured defaultDataLayer data before loading GTM
  • Adds a <noscript> iframe fallback in the <body> for users with JavaScript disabled
  • Includes Web Vitals polyfill when enableWebVitalsTracking is enabled
  • Constructs environment parameter strings when gtmAuth and gtmPreview are both provided
  • Removes trailing slashes from selfHostedOrigin for proper URL construction

Core Web Vitals Tracking

Optional performance monitoring that sends Core Web Vitals metrics to GTM.

/**
 * Gatsby browser lifecycle hook that initializes Web Vitals tracking
 * Automatically called by Gatsby on initial page load
 * @param _ - Gatsby API object (unused)  
 * @param pluginOptions - Plugin configuration options
 */
function onInitialClientRender(_: any, pluginOptions: PluginOptions): void;

When enableWebVitalsTracking is set to true, the plugin automatically:

  • Loads the web-vitals/base library and includes a polyfill script for accurate measurement in non-Chromium browsers
  • Tracks Largest Contentful Paint (LCP), First Input Delay (FID), and Cumulative Layout Shift (CLS)
  • Sends metrics to GTM data layer with debouncing (3000ms timeout for CLS/LCP) and deduplication to prevent duplicate reports
  • Only functions in production mode regardless of the enableWebVitalsTracking setting value

Web Vitals Data Layer Events:

// Example Core Web Vitals event sent to data layer
{
  event: "core-web-vitals",
  webVitalsMeasurement: {
    name: "LCP",        // Metric name: "LCP", "FID", or "CLS"
    id: "unique-id",    // Unique identifier for this page load
    value: 1250         // Metric value (rounded integer, CLS multiplied by 1000)
  }
}

Plugin Lifecycle Integration

The plugin integrates with Gatsby's plugin system through standard lifecycle hooks.

/**
 * Gatsby Node lifecycle hook for preprocessing plugin options
 * Automatically called by Gatsby during build initialization
 * @param args - Gatsby Node API arguments
 * @param options - Raw plugin options from gatsby-config.js
 */
function onPreInit(args: any, options: PluginOptions): void;

/**
 * Plugin options validation schema using Joi
 * Automatically called by Gatsby to validate plugin configuration
 * @param schemaUtils - Gatsby schema utilities containing Joi
 * @returns Joi validation schema object
 */
function pluginOptionsSchema(schemaUtils: { Joi: any }): any;

The plugin automatically handles:

  • Validation of all configuration options with detailed error messages
  • Preprocessing of function-based defaultDataLayer options for serialization
  • Integration with Gatsby's development/production environment detection

Error Handling

The plugin includes comprehensive error handling:

  • Invalid defaultDataLayer: Throws descriptive errors for non-object, non-function values
  • Missing GTM ID: Joi validation ensures required configuration is provided
  • Environment Detection: Automatically respects NODE_ENV settings unless overridden
  • Graceful Degradation: Includes noscript fallback for users with JavaScript disabled

Environment Behavior

  • Production: GTM scripts are loaded by default
  • Development: GTM scripts are not loaded unless includeInDevelopment: true
  • Web Vitals: Only tracked in production mode regardless of enableWebVitalsTracking setting

Dependencies

The plugin has minimal runtime dependencies:

  • @babel/runtime: ^7.20.13 - Runtime helpers for transpiled code
  • web-vitals: ^1.1.2 - Core Web Vitals measurement library (only loaded when tracking enabled)
  • react: ^18.0.0 (peer dependency) - For JSX components in SSR
  • gatsby: ^5.0.0-next (peer dependency) - Gatsby framework compatibility