Recently, we were asked to take over The Bagnall Centre website and migrate the site away from their previous agency’s proprietary CMS. The old website was flaky and unreliable, so we needed something robust & secure that we could maintain easily and our client could update. We chose the JAMstack (JavaScript, APIs & Markup).
Why JAMstack?
Why did we choose the JAMstack over something like WordPress? The primary reasons were the increased security & low maintenance over the old solution. JAMstack is secure by default, when all you have is HTML/CSS/JS there is very little that can be compromised. The JAMstack was the way to go, leaving us with two choices: Hugo or Gatsby. We typically jump between one or the other depending on requirements & complexity. We opted for Hugo due to its simplicity and the existing markup/CSS that we could easily port over.
Moving To Hugo
As we’re now using the JAMstack, there are features from the previous site that need to be rewritten to remove the dependency on server-side PHP, which was used to power the search, login, timetable, and contact forms across the site.
The search was rewritten to use Algolia, which, combined with their instantsearch.js library, was a joy to implement. It’s fast, easily customisable and offers some great features through their dashboard that the old website didn’t have access to.
The contact forms were replaced with Netlify Forms, allowing us more flexibility with how we handle form submissions.
One of the reasons we chose to write the Bagnall Centre website in Hugo was due to the way we received the source code.
Unfortunately, we were denied access to the CMS, forcing us to download each webpage individually, giving us only the HTML, CSS & images to work with.
With access to the live site, we proceeded to piece together the repeating elements of the site using partials and HTML layouts, placing content in Markdown files as we went.
Quickly the site took shape, giving us time to make markup, security & performance improvements.
Security
The first thing we noticed is that the old website was not served over HTTPS. A must-have, considering the old website provided users with the ability to “login” with their username & password. This led us to check the HTTP security headers, for which we used securityheaders.io. We found that none of the recommendations had been met, resulting in a score of “F” for the site.

To rectify this, we added the following security headers, which brings the new score up to an A:
- X-Content-Type-Options
- X-Frame-Options
- X-XSS-Protection
- Referrer-Policty
- Strict-Transport-Security
jQuery
We also detected an outdated version of jQuery (1.7.2), which contained two security vulnerabilities. This was an easy fix with an upgrade to the latest jQuery (3.3.1).
Performance
Improving performance was more of a challenge, as the current website was already reasonably optimised. Making every performance gain, no matter how small, is still essential.
We ran the site through numerous performance measuring tools such as GTMetrix, Lighthouse, WebPageTest & Google Page Speed to get an accurate idea of what, if any, performance upgrades we could make.
JavaScript
Where applicable, we rewrote small jQuery functions as JavaScript to take advantage of any small speed gains we could find.
For example, from:
function handleFormInjection () {
var textarea = $('textarea#message');
if (!textarea.length && !window.location.search.length) {
return;
}
textarea.val(
'I would like to book onto ' + getUrlParameter('course') + ' on ' +
getUrlParameter('day') + ' starting at ' + getUrlParameter('time') +
' with ' + getUrlParameter('associate')
);
}
to:
function handleFormInjection () {
var textarea = document.querySelector('textarea#message');
if (!textarea || !window.location.search.length) {
return;
}
textarea.value = `I would like to book onto ${getUrlParameter('course')} on ${getUrlParameter('day')} starting at ${getUrlParameter('time')}
with ${getUrlParameter('associate')}`;
}
Furthermore, we removed any unnecessary libraries and replaced them with native equivalents. As an example, we removed Mailchimp’s validation and replaced it with HTML5 Form validation.
Any blocking scripts in the header we moved to the footer, making the initial load faster.
CSS
Not much time was spent on styling, as the CSS was already written from the handover. Rewriting & optimising repeating elements proved to reduce the overall file size & load times marginally.
Netlify (Hosting)
Hosting was an easy choice, Netlify offers several tools and services, making JAMStack sites a pleasure to work on.
One of Netlify’s many features is its post-processing, which handles asset optimisation for the site, from pretty URLs to image compression.
Post processing also handles the minification & bundling of CSS & JS, meaning we did not need to spend time updating our build process.

Accessibility
Since the design of the original site remained unchanged, our accessibility improvements focused on enhancing markup to be more semantic and screen reader-friendly.
We used an online tool (Tenon.io) to test the site for poor Accessibility practices. Going through the report, we updated the site by adding alt tags, updating link and button content to be more informative, adding labels to form elements, and setting the page language.