See you at Piwik PRO Meetup’26 Rotterdam!

How we build our website

At our core, we are problem-solvers who love working with data and technology. So when it came to building our own website, we wanted a process that was modern, efficient, and flexible. In this article, we’ll walk you through the technologies we use and the workflow we’ve established to create and maintain our site.

Our choice of tool? The static site generator Hugo.

Our tech stack & theming

We chose Hugo because it’s incredibly fast, secure, and offers powerful features right out of the box. A static site means there’s no database to manage and a significantly smaller attack surface, which aligns perfectly with our focus on efficiency and security.

The foundation: themes and customization

Our website’s visual foundation starts with the hugo-theme-marketing-engineers theme. It provided a great starting point, but we believe a website should be tailored to its specific needs. Therefore, we’ve built a layer of our own customizations on top of it.

Our approach is to override and extend the theme. For features unique to our site, we create custom CSS and HTML files. This keeps our modifications organized and separate from the original theme code, making future updates much easier.

A few examples of our custom components include:

  • Custom Blockquotes: We designed a unique style for our blockquotes and implemented it with a dedicated CSS file and a custom Hugo shortcode.
  • Image Carousels: To showcase images dynamically, we built our own image carousel, complete with its own shortcode and styling.
  • Embedded PDFs: We use the hugo-embed-pdf-shortcode to seamlessly embed PDF documents directly into our pages.

Configuration: the brains of the operation

The hugo.toml file is the central configuration for our site. Here, we manage key settings that define how the website behaves.

  • Multilingual Support: Our content is available in multiple languages. We manage this using Hugo’s language configuration, allowing us to serve both English and Dutch versions of our site:

    [languages]
      [languages.en]
        languageName = 'English'
        languageCode = 'en-US'
        weight = 1
    
      [languages.nl]
        languageName = 'Dutch'
        languageCode = 'nl-NL'
        weight = 2
    
  • Controlling AI Crawlers: We believe in controlling how our content is used by AI models. We recently implemented a rule to generate a llms.txt file to disallow scraping by common AI bots:

    [Params.robots]
      llmsTXT = true
    

Content & features

Our website is more than just a brochure; it’s a platform for sharing knowledge and updates. Hugo’s content management capabilities allow us to structure our information logically.

Content structure

Our articles are organized into two main categories:

Beyond articles, we have dedicated pages for our team, our favorite platforms & technologies, our services, case studies, and a list of events we’re participating in.

Writing content with Markdown

All our content is written in Markdown, which makes the writing process fast and straightforward. We use a consistent set of metadata fields in the “front matter” at the top of each file:

  • title: The main title of the page or article.
  • description: A brief summary used for SEO and previews.
  • date: The publication date.
  • article: A custom field to categorize the content.
  • author: The name of the writer.
  • ai_description: A flag related to AI processing.

Custom Shortcodes for dynamic content

To embed complex or interactive elements, we rely on Hugo’s shortcodes. We’ve built several custom ones:

  • An <iframe> shortcode for embedding dashboards.
  • A shortcode for our contact form.
  • The aforementioned image carousel.

For managing images, we’ve combined a shortcode with Hugo’s built-in Resize function. This allows us to automatically create smaller, web-optimized versions of large images, improving page load times.

Our development & deployment workflow

A solid workflow is key to maintaining quality and efficiency. Ours is built around industry-standard tools like Git and is designed for seamless collaboration.

  • Local Development: When we work on the site, we use Hugo’s built-in web server with the command

    hugo server --disableFastRender --renderToMemory
    

    This instantly reloads the page after we save the changes, allowing for rapid development and testing.

  • Version Control: The entire website’s source code is managed with Git and hosted on GitHub. This gives us a complete history of every change.

  • Collaboration & Staging: When a team member writes a new article, our developer converts it to Markdown and pushes the changes to a staging branch on GitHub. This automatically deploys a preview version of the site. The team can then review the live staging link and provide feedback before the changes go public.

Performance & Optimization

A fast website provides a better user experience and ranks higher in search results. We take performance seriously.

Asset Pipeline

We use Hugo Pipes, the built-in asset pipeline, to automatically minify our CSS and JavaScript files. This leads to faster loading times.

Live Performance Monitoring

We believe in data-driven decisions. That’s why we created a public-facing Web Vitals dashboard. This dashboard displays live metrics for our website’s health, focusing on Google’s Core Web Vitals. Specifically, we monitor:

  • LCP (Largest Contentful Paint): How quickly the main content of a page becomes visible.
  • INP (Interaction to Next Paint): How quickly the page responds to user interactions like clicks or taps.
  • CLS (Cumulative Layout Shift): How much the page layout unexpectedly shifts during loading.
  • FCP (First Contentful Paint): How long it takes for the very first piece of content to appear on screen.

Tracking these key indicators allows us to proactively identify and fix issues, ensuring a smooth and fast experience for our visitors.