Building a popular posts widget in Eleventy using Plausible analytics

I took some time last week to build out a popular posts widget after seeing Zach's implementation using Google Analytics.

Plausible offers access to an API to query and return stats collected from visitors to your site.

My request to Plausible's API looks like this:

const EleventyFetch = require('@11ty/eleventy-fetch')

module.exports = async function () {
  const url =
  const res = EleventyFetch(url, {
    duration: '1h',
    type: 'json',
    fetchOptions: {
      headers: {
        Authorization: `Bearer ${API_KEY_PLAUSIBLE}`,
  const pages = await res
  return pages.results.filter((p) =>'posts')).splice(0, 5)

This is then passed to a custom filter (based on code I originally stole from Zach):

getPopularPosts: (posts, analytics) => {
  return posts
    .filter((post) => {
      if (analytics.find((p) => === post.url)) return true
    .sort((a, b) => {
      const visitors = (page) => analytics.filter((p) => === page.url).pop().visitors
      return visitors(b) - visitors(a)

And rendered using a liquid template:

{% assign posts = posts | getPopularPosts: analytics %}
<div class="not-prose">
  <h2 class="[&>svg]:h-7 [&>svg]:w-7 [&>svg]:inline icon--bold m-0 text-xl flex flex-row items-center font-black leading-tight tracking-normal dark:text-gray-200 md:text-2xl mt-8 mb-4">
    {% tablericon "fire" "Popular" %}
    Popular posts
  <ul class="list-inside list-disc pl-5 md:pl-10">
    {% for post in posts %}
      <li class="mt-1.5 mb-2">
        <a href="{{post.url}}" title="{{ | escape}}">
          {{ }}
    {% endfor %}

This can then be rendered just about anywhere using the following:

{% render "partials/popular-posts.liquid", posts: collections.posts, analytics: analytics %}

And can be seen on my handy, dandy 404 (or search or any post page).

Cory Dransfeldt
Cory Dransfeldt

I'm a software developer in Camarillo, California. I enjoy hanging out with my beautiful family and 4 rescue dogs, technology, automation, music, writing, reading and tv and movies.