Skip to main content
The primary way to install Grain. Perfect for any website — landing pages, static sites, CMSs, or full web apps. No build tools required.
Using React or Next.js? Try React Quick Start or Next.js Quick Start for hooks-based integration.

Add the Script Tag

Add this to your HTML <head>:
<script src="https://tag.grainql.com/v4/your-tenant-id.js"></script>
<script>
  // SDK auto-initializes, get the instance
  const grain = GrainTag.getInstance();

  // Track custom events
  grain.track('button_clicked', {
    button_id: 'signup'
  });
</script>
Replace your-tenant-id with your tenant identifier (not UUID) from your dashboard. That’s it! Grain is now loaded and tracking.

Complete HTML Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Landing Page</title>

  <!-- Grain Tag (auto-initializes) -->
  <script src="https://tag.grainql.com/v4/your-tenant-id.js"></script>
</head>
<body>
  <h1>Welcome!</h1>
  <button id="signup-btn">Get Started</button>

  <script>
    // Get SDK instance (already initialized)
    const grain = GrainTag.getInstance();

    // Track button clicks
    document.getElementById('signup-btn').addEventListener('click', function() {
      grain.track('signup_clicked', {
        location: 'hero'
      });

      // Your signup logic...
      window.location.href = '/signup';
    });
  </script>
</body>
</html>

Track Form Submissions

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

<script>
  document.getElementById('contact-form').addEventListener('submit', function(e) {
    e.preventDefault();

    // Track the submission
    grain.track('form_submitted', {
      form_name: 'contact',
      page: window.location.pathname
    });

    // Your form submission logic...
  });
</script>
<a href="/pricing" id="pricing-link">View Pricing</a>

<script>
  document.getElementById('pricing-link').addEventListener('click', function() {
    grain.track('link_clicked', {
      link_text: 'View Pricing',
      destination: '/pricing'
    });
  });
</script>

Use Remote Configuration

Control your page content without redeploying:
<div id="promo-banner" style="display: none;">
  <p id="promo-text">Special offer!</p>
</div>

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Check if banner should show
    const showBanner = grain.getConfig('show_promo_banner');
    const bannerText = grain.getConfig('promo_banner_text');

    if (showBanner === 'true') {
      document.getElementById('promo-banner').style.display = 'block';
      document.getElementById('promo-text').textContent = bannerText || 'Special offer!';
    }
  });
</script>
Now you can toggle the banner on/off from your dashboard without touching your code!

Identify Users

Track logged-in users:
<script>
  // When user logs in — pass only the user ID
  function handleLogin(userId) {
    grain.identify(userId);

    // Track login event
    grain.track('user_logged_in', {
      method: 'email'
    });
  }
</script>

Track Page Views on Navigation

For multi-page sites, the script automatically tracks each page load. For single-page apps:
<script>
  // Track browser back/forward
  window.addEventListener('popstate', function() {
    grain.track('page_viewed', {
      page: window.location.pathname
    });
  });

  // Track custom navigation
  function navigateTo(url) {
    history.pushState(null, '', url);

    grain.track('page_viewed', {
      page: url
    });

    // Your navigation logic...
  }
</script>

Performance Tips

Do: Place Grain in the <head> for early initialization
Do: Use one script tag per page — Grain handles everything
Don’t: Load Grain multiple times — once per page is enough

What’s Next?

Core API Reference

See all available methods and options

Event Tracking Guide

Learn what to track and best practices

Remote Config Guide

Master configuration and feature flags

Trackers

Track element clicks without code
Using Google Tag Manager instead? Check out the GTM Integration Guide for a no-code setup.