Tracking Post Series Engagement in Jekyll Without a Backend

Why Track Post Series Navigation?

After building contextual navigation between posts in a series, the next step is understanding how readers engage with that flow:

  • Are they completing the entire series?
  • Do they drop off at a particular part?
  • Which parts are revisited?

Traditional analytics tools like Google Analytics may feel like overkill or may not offer fine-grained, privacy-friendly insights. Let's explore a lightweight, backend-free approach tailored for Jekyll sites.

Step 1: Use localStorage to Track Progress

The simplest method is to record which parts a user has read using localStorage. Here’s a JavaScript snippet you can include in your layout:

<script>
(function() {
  const key = 'jekyll_series_progress';
  const series = "{{ page.series.name | escape }}";
  const part = "{{ page.series.part }}";

  if (series && part) {
    let progress = JSON.parse(localStorage.getItem(key) || '{}');

    if (!progress[series]) {
      progress[series] = [];
    }

    if (!progress[series].includes(part)) {
      progress[series].push(part);
    }

    localStorage.setItem(key, JSON.stringify(progress));
  }
})();
</script>

This script stores the user's read parts for each series as an object. You can use this later to display a dynamic "Your Progress" UI.

Step 2: Show Reading Progress Visually

To make this data useful, render a visual progress bar. Add this near your series navigation box:

<script>
(function() {
  const key = 'jekyll_series_progress';
  const series = "{{ page.series.name | escape }}";
  const totalParts = {{ site.data.series[page.series.name].size }};
  const progress = JSON.parse(localStorage.getItem(key) || '{}');

  if (progress[series]) {
    const readParts = progress[series].length;
    const percent = Math.round((readParts / totalParts) * 100);

    const progressEl = document.getElementById('series-progress');
    if (progressEl) {
      progressEl.innerHTML = `You’ve read ${readParts} of ${totalParts} parts (${percent}%)`;
    }
  }
})();
</script>

<div id="series-progress"></div>

Step 3: Optional – Log Data to GitHub Issues

If you'd like to log anonymous progress data publicly without a backend, you can use GitHub's Issues API. You’ll need:

  • A GitHub personal access token (with public_repo scope)
  • A dedicated repository for tracking logs

Example of sending an anonymous log via GitHub's API:


fetch('https://api.github.com/repos/YOUR_USERNAME/YOUR_REPO/issues', {
  method: 'POST',
  headers: {
    'Authorization': 'token YOUR_PERSONAL_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: `Series Read: ${series}, Part ${part}`,
    body: `Anonymous user read part ${part} of series ${series} at ${new Date().toISOString()}.`,
    labels: ['engagement', 'series-tracking']
  })
});

Note: This should be used sparingly and not on every page load. Consider adding a “submit feedback” button instead that triggers the logging manually.

Step 4: Privacy Considerations

This approach uses:

  • localStorage for client-side persistence (no network transmission)
  • GitHub Issues as an optional, user-controlled method to share engagement (fully transparent)

No personal data is captured unless you explicitly ask for it or link GitHub accounts to readers (which is not recommended for anonymous tracking).

Advanced Enhancements

  • Trigger a confetti or badge once a series is completed
  • Show estimated time remaining based on unread parts
  • Store and retrieve series bookmarks or annotations (via cookies or IndexedDB)

Conclusion

Tracking series engagement in Jekyll doesn't require Google Analytics or third-party scripts. By leveraging localStorage, you can offer meaningful user feedback, enhance UX, and maintain privacy—all while staying fully static and GitHub Pages–friendly.

Next Steps

In the next article, we’ll dive into building a personal reading dashboard for returning visitors using localStorage and JavaScript—think of it as a "Continue Where You Left Off" for static blogs.


Archives / All Content


© HypeLeakDance . All rights reserved.