Home Blog How to Add Google Analytics to Your Jekyll Site
Tutorial

How to Add Google Analytics to Your Jekyll Site

Add Google Analytics 4 to Jekyll in under 5 minutes — with the tracking snippet, privacy-friendly loading, and how to verify it's working correctly.

How to Add Google Analytics to Your Jekyll Site

Adding Google Analytics to Jekyll takes about 5 minutes. This guide covers Google Analytics 4 (GA4), the only version Google currently supports, plus tips for privacy-friendly loading and verifying it works.


What You Need

  • A Google account
  • Your Jekyll site’s URL
  • Access to your Jekyll theme files

Step 1: Create a GA4 Property

  1. Go to analytics.google.com
  2. Click Admin (gear icon, bottom left)
  3. Click CreateProperty
  4. Enter your property name and time zone, click Next
  5. Fill in your business details, click Create
  6. Choose Web as the platform
  7. Enter your website URL and stream name
  8. Click Create stream

You’ll see your Measurement ID — it looks like G-XXXXXXXXXX. Copy it.


Step 2: Add Your Measurement ID to _config.yml

Store the ID in your config so it’s easy to change and easy to disable:

# _config.yml
google_analytics: G-XXXXXXXXXX

Step 3: Create the Analytics Include

Create _includes/analytics.html:


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

The {% if site.google_analytics %} check means analytics only loads when the ID is set — remove the ID from _config.yml to disable tracking entirely.


Step 4: Add to Your Layout

In _layouts/default.html, add the include just before </head>:


<head>
  <!-- your existing head content -->
  {% include analytics.html %}
</head>


Step 5: Disable Analytics in Development

You don’t want to track your own visits while building locally. Jekyll sets JEKYLL_ENV to development by default locally and production on most hosts.

Update your include to only load in production:


{% if site.google_analytics and jekyll.environment == 'production' %}
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', '{{ site.google_analytics }}');
</script>
{% endif %}

Make sure your deployment sets the environment variable:

# Netlify / Cloudflare Pages — add environment variable:
JEKYLL_ENV=production

GitHub Actions already sets this in the default Jekyll workflow.


Step 6: Verify It’s Working

Method A: Real-time report

  1. Open Google Analytics → Reports → Realtime
  2. Open your live site in another tab
  3. You should see yourself as an active user within 30 seconds

Method B: Browser Dev Tools

  1. Open your live site
  2. Open DevTools → Network tab
  3. Filter by google or gtag
  4. Refresh the page — you should see requests to googletagmanager.com

Method C: GA4 Debugger Install the Google Analytics Debugger Chrome extension. It logs all GA4 events to the console.


GDPR requires user consent before setting analytics cookies in the EU. If your audience is European or you want to be safe:


{% if site.google_analytics and jekyll.environment == 'production' %}
<script>
  // Only load GA after user clicks "Accept"
  function loadAnalytics() {
    var s = document.createElement('script');
    s.src = 'https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}';
    s.async = true;
    document.head.appendChild(s);
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', '{{ site.google_analytics }}');
  }
  
  if (localStorage.getItem('analytics_consent') === 'true') {
    loadAnalytics();
  }
</script>
{% endif %}

Option B: Switch to a Privacy-First Alternative

If GDPR compliance is important, consider:

  • Plausible Analytics — no cookies, GDPR compliant, $9/month. Add with one script tag.
  • Fathom Analytics — similar to Plausible, privacy-first
  • Cloudflare Web Analytics — free, no cookies, built into Cloudflare Pages

For Plausible:


{% if site.plausible_domain and jekyll.environment == 'production' %}
<script defer data-domain="{{ site.plausible_domain }}" 
        src="https://plausible.io/js/script.js"></script>
{% endif %}

# _config.yml
plausible_domain: yourdomain.com

Common Issues

Analytics not showing data

  • Check that JEKYLL_ENV=production is set in your deployment environment
  • Verify the script is in the <head> of your built HTML (view source on the live site)
  • Check browser console for errors
  • Make sure you’re not running an ad blocker that blocks GA

Seeing your own visits in reports

  • You’re either not using the jekyll.environment == 'production' check, or JEKYLL_ENV isn’t being set correctly on your host
  • Install the Block Yourself from Analytics Chrome extension

Data appears in GA but with wrong URL

  • Check url in _config.yml — it should be your full domain with https://
  • In GA4, verify the data stream URL matches your live site URL

Once GA4 is tracking, wait 24–48 hours and then check Reports → Acquisition → Traffic acquisition to see where your visitors are coming from. For a new site, most traffic will be direct initially — organic search traffic grows over weeks as Google indexes your posts.

Browse Jekyll themes on JekyllHub — many themes include pre-configured analytics support in their _config.yml.


Understanding GA4 reports for Jekyll blogs

Once GA4 is tracking, the reports that matter most for a content site are different from what you would monitor for an e-commerce site. For a Jekyll blog, focus on these specific areas.

Engagement rate (Reports → Acquisition → Traffic acquisition) has largely replaced the old “bounce rate” in GA4. An engagement rate above 50% means more than half your sessions include at least one of these: a page view lasting more than 10 seconds, a second page view, or a conversion event. For a blog, 50–70% is healthy. Below 40% suggests users are landing on pages that do not match their intent.

Pages and screens (Reports → Engagement → Pages and screens) shows your most-visited content. Sort by “Views” to see your top posts. Sort by “Average engagement time” to see which posts hold attention longest. Your highest-traffic but lowest-engagement posts are candidates for improvement — they are attracting clicks but not delivering what readers expected.

Search console integration connects GA4 to your Google Search Console property, adding a “Google organic search” dimension that shows which search queries bring visitors to specific pages. This is the most direct signal you have for SEO performance. Go to Admin → Product links → Search Console to connect the two properties.

Conversion tracking for a blog typically means tracking newsletter signups, clicks to your email address, clicks to external resources you recommend, or downloads. Create GA4 conversion events for these actions using the event tracking snippet:

// Track newsletter signup
document.getElementById('newsletter-form').addEventListener('submit', () => {
  gtag('event', 'newsletter_signup', {
    event_category: 'engagement',
    event_label: 'footer_form'
  });
});

// Track external link clicks
document.querySelectorAll('a[href^="http"]').forEach(link => {
  link.addEventListener('click', () => {
    gtag('event', 'click', {
      event_category: 'outbound',
      event_label: link.href
    });
  });
});

Mark these events as conversions in GA4 under Admin → Events → Mark as conversion. Conversion tracking turns GA4 from a traffic counter into a tool that connects visitor behaviour to business outcomes.

Filtering out your own traffic

Your own visits to your site inflate traffic numbers and distort behavioural data. The production environment guard (jekyll.environment == 'production') prevents tracking during local development, but does not prevent tracking when you visit your live site from your own browser.

The cleanest solution is to block yourself in GA4 using an IP address filter. Go to Admin → Data Streams → your stream → Configure tag settings → Define internal traffic → Create, and add your home or office IP address. Then go to Admin → Data Filters → Create filter → Internal Traffic and set the filter to “Active” to exclude this traffic from all reports.

For dynamic IP addresses, the Google Analytics Opt-out Browser Add-on (available for Chrome, Firefox, Safari, and Edge) prevents GA from tracking any browser where it is installed. Install it on your personal browsers and you will never appear in your own analytics data.

Setting up goals around content milestones

Most Jekyll blogs are not tracking conversions beyond newsletter signups. Adding a few more goal events creates a richer picture of how readers engage with your content.

Track scroll depth to understand how far readers get through long posts. A simple implementation using Intersection Observer:

const articleEnd = document.querySelector('.post-content-end');
if (articleEnd) {
  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        gtag('event', 'article_read', {
          event_category: 'engagement',
          event_label: document.title
        });
        observer.unobserve(entry.target);
      }
    });
  }, { threshold: 0.5 });
  observer.observe(articleEnd);
}

Add <div class="post-content-end"></div> at the end of your post layout. When the element enters the viewport, the article_read event fires. Track the percentage of visitors who trigger this event per post — posts with low read-through rates may need better structure, more engaging opening sections, or a more accurate title that sets correct expectations.

GA4’s free tier is sufficient for the vast majority of Jekyll blogs. The paid version (Google Analytics 360) adds features like BigQuery export, unsampled reports, and extended data retention — none of which are relevant until you are handling tens of millions of monthly page views. For the scale of any personal blog or small business site, GA4’s free tier plus the techniques in this guide gives you everything you need to make data-informed content decisions.

Using GA4 alongside privacy-first alternatives

Many site owners run both Google Analytics and a privacy-first tool simultaneously. GA4 provides the depth of data — user flows, session recordings integration points, conversion attribution — while Plausible or Fathom provides a fast-loading, cookieless dashboard for daily monitoring that does not require a consent banner for EU visitors.

The practical pattern: use Plausible for day-to-day traffic monitoring (it is faster to check and requires no consent logic), and use GA4 for deeper quarterly analysis — user acquisition pathways, content performance, conversion funnel optimisation, and Search Console integration. Each tool has different strengths, and running them simultaneously is not technically problematic since they are independent scripts with minimal performance overlap.

If you are starting fresh and simplicity is your priority, start with Plausible alone. You can always add GA4 later when you need its deeper analytics capabilities. If you already have GA4 set up and have historical data you want to preserve, keep it and add Plausible as a faster, privacy-compliant dashboard for routine checks.

The Jekyll implementation for both is identical in structure — an include file containing the script tag, loaded conditionally on production builds via {% if jekyll.environment == 'production' %}. The habit of using this guard on all analytics and tracking scripts is one of the most consistently useful practices in Jekyll development, ensuring your local development data never contaminates your production metrics.

Reviewing your analytics regularly

The best analytics setup is one you actually use. Set a recurring reminder — weekly or monthly depending on your site’s traffic level — to open your analytics dashboard and look at three things: which posts are driving the most traffic, where visitors are coming from, and what your bounce rate looks like on mobile. These three data points will consistently surface the most actionable improvements to your content and site structure. Analytics only has value when it informs decisions, so build the habit of regular review from the day you install it.

Share LinkedIn