
Writing statistics for your Eleventy (11ty) blog
One of the reasons why I switched to Eleventy was to make it easier to do custom stuff, like creating a writing statistics page for my needs. This blog post is to share how I created that page and how you can create one for your blog.
The problem #
My old blog was written in Jekyll. The stats page was incredibly complicated with a lot of template logic. There was also a mess of Python scripts to generate data.
Because of this, one of my fundamental design decisions was to do as much as possible in JavaScript. The data generated by this JavaScript code should match how it is used on the page. The liquid template should just render the data into HTML.
{
"spotlight": [
{
"title": "Total words written",
"icon": "pen",
"value": 46891
},
{
"title": "Total posts",
"icon": "newspaper",
"value": 78
},
{
"title": "Total likes received",
"icon": "heart",
"value": 322,
"hint": " Experimental, currently only counts Mastodon likes"
}
],
"by_year": {
"2023": {
"total": 14,
"wc_total": 15455,
"wc_avg": 1104
},
"2024": {
"total": 5,
"wc_total": 3940,
"wc_avg": 788
},
"2025": {
"total": 8,
"wc_total": 5021,
"wc_avg": 628
}
}
}
How it works #
Register the stats plugin #
const pluginStats = require("./plugins/stats.js");
module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(pluginStats);
}
Stats.js #
To make it as flexible as possible, we use a filter to pass in the posts to generate data for.
function buildStats(collection) {
return {};
}
/**
* @param {UserConfig} eleventyConfig
* @returns {void}
*/
export default function (eleventyConfig) {
eleventyConfig.addFilter("stats", buildStats);
}
This buildStats
is the meat of the stats page. You can use
my wordcount plugin to generate word counts for each
post and then aggregate these word points by year, tag, or get a total. For my
implementation, see https://gitlab.com/rubenwardy/eleventy-stats-example.
HTML #
The HTML page can pass in the post collection to get statistics:
{% assign stats = collections.post | stats %}
<section id="by-year">
<h2>By year</h2>
<div class="row row-wrap gap-4">
<div class="col-md">
<h3 class="mt-0 mb-3">Number of posts</h3>
{% include "bar_chart.html" data: stats.by_year, value_key: "total" %}
</div>
<div class="col-md">
<h3 class="mt-0 mb-3">Total words</h3>
{% include "bar_chart.html" data: stats.by_year, value_key: "wc_total" %}
</div>
<div class="col-md">
<h3 class="mt-0 mb-3">Average post word count</h3>
{% include "bar_chart.html" data: stats.by_year, value_key: "wc_avg" %}
</div>
</div>
</section>
Conclusion #
Hopefully, this was useful as an example on how to get started with creating a writing stats page for your blog. The power of Eleventy is how easy it is to create custom logic and behaviour for your websites, so you should definitely modify this for your needs.
Again, a full working example is available at https://gitlab.com/rubenwardy/eleventy-stats-example.
Comments