Skip to content
Back to skills

2514 Gtag Bef05560

ASecurity

Expert guidance for implementing GA4 using gtag.js directly without Google Tag Manager.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentjavascripttypescriptgojavareactvueangularnextjstesting

Works with

  • cli

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2514-gtag_bef05560 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2514 Gtag Bef05560?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2514 Gtag Bef05560
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2514-gtag-bef05560/badge)](https://www.skillsdirectory.com/skills/tools-only-2514-gtag-bef05560)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# GA4 gtag.js Direct Implementation

Expert guidance for implementing GA4 using gtag.js directly without Google Tag Manager.

## Overview

gtag.js (Google Tag) is the official JavaScript library for implementing GA4 tracking directly on websites. This reference covers installation, gtag commands, event tracking, user properties, and framework integration patterns.

## When to Use gtag.js

**Choose gtag.js when:**
- Only need Google products (GA4, Google Ads)
- Want lightweight implementation
- Have code access to website
- No tag management system required
- Simple tracking needs

**Choose GTM instead when:**
- Need multiple tracking tags
- Team collaboration required
- Frequent changes expected
- Want version control for tags

## Installation

### Basic Installation

Place in `<head>` section, before all other scripts:

```html
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>
```

### Placement Requirements

| Requirement | Description |
|-------------|-------------|
| Location | `<head>` section |
| Position | Before all other scripts |
| Async | Script loaded asynchronously |
| Every page | Must be on all pages |

## gtag Commands

### gtag('js', new Date())

Initialises the library with timestamp.

```javascript
gtag('js', new Date());
```

**Required:** Yes, must be called first

### gtag('config', 'G-ID')

Configures GA4 with Measurement ID.

**Basic:**
```javascript
gtag('config', 'G-XXXXXXXXXX');
```

**With Options:**
```javascript
gtag('config', 'G-XXXXXXXXXX', {
  'page_title': 'Custom Page Title',
  'page_location': window.location.href,
  'send_page_view': true,
  'allow_google_signals': true,
  'allow_ad_personalization_signals': true,
  'user_id': 'USER_12345'
});
```

### gtag('event', 'name', {params})

Sends events to GA4.

**Simple Event:**
```javascript
gtag('event', 'button_click', {
  'button_name': 'Subscribe',
  'button_location': 'header'
});
```

**Recommended Event:**
```javascript
gtag('event', 'purchase', {
  'transaction_id': 'TXN_12345',
  'value': 99.99,
  'currency': 'USD',
  'items': [{
    'item_id': 'SKU_001',
    'item_name': 'Product Name',
    'price': 99.99,
    'quantity': 1
  }]
});
```

### gtag('set', {properties})

Sets user properties and User ID.

**User ID:**
```javascript
// On login
gtag('set', 'user_id', 'USER_12345');

// On logout - MUST use null, never empty string
gtag('set', 'user_id', null);
```

**User Properties:**
```javascript
gtag('set', 'user_properties', {
  'subscription_tier': 'premium',
  'customer_segment': 'enterprise',
  'account_age_days': 365
});
```

### gtag('consent', 'default/update', {})

Manages consent state.

**Default (Before Consent):**
```javascript
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'analytics_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied'
});
```

**Update (After Consent):**
```javascript
gtag('consent', 'update', {
  'ad_storage': 'granted',
  'analytics_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted'
});
```

## Common Implementation Patterns

### Button Click Tracking

```html
<button id="subscribe-btn">Subscribe</button>

<script>
document.getElementById('subscribe-btn').addEventListener('click', function() {
  gtag('event', 'button_click', {
    'button_name': 'Subscribe',
    'button_location': 'homepage_hero',
    'button_id': 'subscribe-btn'
  });
});
</script>
```

### Form Submission Tracking

```html
<form id="contact-form">
  <input type="email" name="email" required>
  <button type="submit">Submit</button>
</form>

<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
  gtag('event', 'form_submit', {
    'form_name': 'Contact Form',
    'form_id': 'contact-form',
    'form_destination': '/thank-you'
  });
});
</script>
```

### Video Tracking

```javascript
// Video start
gtag('event', 'video_start', {
  'video_title': 'Getting Started Guide',
  'video_id': 'VID_001',
  'video_duration': 180
});

// Video progress
gtag('event', 'video_progress', {
  'video_title': 'Getting Started Guide',
  'video_id': 'VID_001',
  'video_percent': 50
});

// Video complete
gtag('event', 'video_complete', {
  'video_title': 'Getting Started Guide',
  'video_id': 'VID_001'
});
```

### Ecommerce Purchase

```javascript
gtag('event', 'purchase', {
  'transaction_id': 'TXN_' + Date.now(),
  'value': 149.99,
  'currency': 'USD',
  'tax': 10.00,
  'shipping': 5.99,
  'coupon': 'SUMMER20',
  'items': [
    {
      'item_id': 'SKU_001',
      'item_name': 'Premium Widget',
      'item_brand': 'Acme',
      'item_category': 'Electronics',
      'item_variant': 'Blue',
      'price': 149.99,
      'quantity': 1
    }
  ]
});
```

### User Authentication

```javascript
// On login
function handleLogin(userId, method) {
  // Set User ID
  gtag('set', 'user_id', userId);

  // Send login event
  gtag('event', 'login', {
    'method': method
  });

  // Set user properties
  gtag('set', 'user_properties', {
    'account_type': 'registered',
    'login_method': method
  });
}

// On logout
function handleLogout() {
  // Clear User ID
  gtag('set', 'user_id', null);

  // Optional: track logout
  gtag('event', 'logout');
}
```

## Single Page Applications

### Manual Page View Tracking

SPAs don't trigger traditional page loads. Track manually:

```javascript
// Call on route change
function trackPageView(path, title) {
  gtag('config', 'G-XXXXXXXXXX', {
    'page_path': path,
    'page_title': title
  });
}

// Example with router
router.afterEach((to) => {
  trackPageView(to.path, to.meta.title);
});
```

### Disable Automatic Page View

If handling manually:

```javascript
gtag('config', 'G-XXXXXXXXXX', {
  'send_page_view': false
});

// Then send manually
gtag('event', 'page_view', {
  'page_title': 'Custom Title',
  'page_location': window.location.href,
  'page_path': '/custom-path'
});
```

## Framework Integration

### React / Next.js

```javascript
// lib/gtag.js
export const GA_MEASUREMENT_ID = 'G-XXXXXXXXXX';

export const pageview = (url) => {
  window.gtag('config', GA_MEASUREMENT_ID, {
    page_path: url,
  });
};

export const event = (action, params) => {
  window.gtag('event', action, params);
};
```

```javascript
// In _app.js or layout
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import * as gtag from '../lib/gtag';

export default function App({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url);
    };
    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);

  return <Component {...pageProps} />;
}
```

### Vue.js

```javascript
// plugins/gtag.js
export default {
  install(app) {
    app.config.globalProperties.$gtag = (action, params) => {
      window.gtag('event', action, params);
    };
  }
};
```

```javascript
// In router
router.afterEach((to, from) => {
  gtag('config', 'G-XXXXXXXXXX', {
    page_path: to.fullPath,
    page_title: to.meta.title
  });
});
```

### Angular

```typescript
// analytics.service.ts
import { Injectable } from '@angular/core';

declare let gtag: Function;

@Injectable({
  providedIn: 'root'
})
export class AnalyticsService {
  event(action: string, params: object) {
    gtag('event', action, params);
  }

  pageView(path: string, title: string) {
    gtag('config', 'G-XXXXXXXXXX', {
      page_path: path,
      page_title: title
    });
  }
}
```

## Multiple Properties

Track to multiple GA4 properties:

```javascript
// Configure both
gtag('config', 'G-XXXXXXXXXX');  // Property 1
gtag('config', 'G-YYYYYYYYYY');  // Property 2

// Events sent to both automatically
gtag('event', 'purchase', {
  'value': 99.99,
  'currency': 'USD'
});

// Send to specific property only
gtag('event', 'purchase', {
  'send_to': 'G-XXXXXXXXXX',
  'value': 99.99,
  'currency': 'USD'
});
```

## Debug Mode

Enable debug mode for testing:

```javascript
gtag('config', 'G-XXXXXXXXXX', {
  'debug_mode': true
});
```

**Important:** Remove for production.

## Common Pitfalls

### 1. gtag Called Before Initialisation

**Problem:** Events called before gtag snippet
**Solution:** Ensure snippet loads first in `<head>`

### 2. Multiple gtag Snippets

**Problem:** Duplicate events
**Solution:** Single snippet, multiple config calls

### 3. Empty String for User ID

**Problem:** User ID not cleared properly
**Solution:** Use `null`, never empty string `""`

### 4. Missing Currency

**Problem:** Monetary events without currency
**Solution:** Always include `currency` with `value`

### 5. Unregistered Parameters

**Problem:** Parameters not in reports
**Solution:** Register as custom dimensions

## Critical Rules

| Rule | Value |
|------|-------|
| Event name max | 40 characters |
| Parameter name max | 40 characters |
| Parameter value max | 100 characters |
| Parameters per event | 25 |
| Event names | snake_case |

## Quick Reference

### Initialise

```javascript
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
```

### Send Event

```javascript
gtag('event', 'event_name', {params});
```

### Set User ID

```javascript
gtag('set', 'user_id', 'USER_123');
```

### Set User Properties

```javascript
gtag('set', 'user_properties', {key: 'value'});
```

### Clear User ID

```javascript
gtag('set', 'user_id', null);
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.