Progressively Enhancing Maps for UK Government Services

Progressively Enhancing Maps for UK Government Services

In this post, I explore how to progressively enhance interactive maps for UK government services, with accessible, resilient fallbacks when JavaScript fails.

Introduction

If there’s one component I distinctly remember frequently being asked about while working at Government Digital Service (GDS), it’s a maps component. You may wonder why that is, well, it’s related to Progressive Enhancement (PE). More specifically, GDS’s unwavering stance on the use of Progressive Enhancement, when building all UK government services. If you don’t know what PE is, then luckily for you, I've written about it before on a previous blog post Hack to the Future - Frontend. This is a huge post I wrote in August 2025 all about what Frontend Development used to look like before sane browser standards existed. Including all the weird and wonderful hacks and workarounds Frontend Developers had to use to make a web page look like a designer wanted. I specifically have a section in that post is all about Progressive Enhancement. So, if you are looking for some information on Progressive Enhancement, I highly recommend having a read of that section before proceeding further. However, if you already know all about it, then please read on, and I do apologise for all the preamble!

Why a maps component?

The answer is pretty simple: if you want a map that’s genuinely interactive and easy to use, there’s really no getting around JavaScript (JS). The clearest example of this functionality on the web is Google Maps. It was first released in February 2005, after Google acquired an Australian mapping startup called Where 2 Technologies in 2004. When Google officially released its own version a year later, it was a genuine game-changer, forever changing how users viewed and interacted with maps online.

Some of the innovations Google Maps brought included:

  • AJAX-based interaction
  • Draggable maps
  • Incremental map loading
  • Tiled map rendering
  • Client-side tile positioning
  • Tile preloading and caching
  • Continuous zoom interaction
  • UI overlays
  • Satellite imagery integration
  • Deep linking and shareable state
  • Google Maps API
  • Progressive rendering
  • Direct manipulation of the User Interface (UI)

Now, I’m not going to cover them all, or this post will become rather long, which wouldn't be entirely out of character for one of my blog posts!

Instead, I want to focus on the three that mattered most from a frontend architecture perspective: AJAX, tiled rendering, and direct UI manipulation. Together, they fundamentally changed how we built for and interacted with the web, influencing frontend architecture and user experience for decades. Their impact is still clearly visible today.

AJAX

For the “older” readers among us (me included! 👴🏼), Ajax may be more familiar as something you cleaned the kitchen with. Web developers had other ideas: AJAX stands for Asynchronous JavaScript and XML. Which is an interesting name considering it doesn’t require the use of XML to work! It just became an umbrella “catch all” term for the technique where JavaScript communicates with a server in the background, thus allowing for a web page to update without having to resort to a full-page refresh. If you’ve ever worked with a Single Page Application (SPA), this will all sound very familiar! AJAX helped pave the way for the architectural approach behind many of the frontend frameworks we see today, including:

The key leap forwards was that AJAX allowed a web application to fetch new data and update parts of the interface without reloading the entire page. Suddenly, websites could behave much more like regular desktop applications, with interactions feeling immediate, fluid, and continuous.

An interesting historical footnote: the technology behind AJAX, XMLHttpRequest, originated as Microsoft’s proprietary ActiveX object XMLHTTP technology in Internet Explorer 5 in 1999. And people say old IE held the web back! I mean, it absolutely did, but we should probably give it this one!

Tiled Rendering

The downside about standard paper maps is you only get them in a singular map scale. For example, 1:50,000 means 1 cm on the map = 50,000 cm in reality, which is 500 metres. However, when it comes to digital maps in a browser that is no longer a constraint. As I’m sure you will have seen when you zoom in and zoom out on Google Maps you get different scaled maps at different zoom levels. This gives a user the ability to see a wide area as well as a tiny area all on the same “map”.

The problem with this fantastic advance in digital cartography is data. Maps contain a lot of it, and downloading an entire map every time the user moves would make for an incredibly sluggish user experience.

This is where tiled rendering comes in. At each zoom level, the map is divided into a grid of small tiles. The browser requests only the tiles needed for the area currently visible, then assembles them into a seamless map.

As the user pans or zooms, new tiles are fetched as required. This reduces unnecessary data transfer and allows users to move far beyond the area they started in, making the map feel fast, continuous, and incredibly intuitive to explore.

And this brings us straight back to AJAX. Those new tiles can be requested asynchronously in the background while the user continues interacting with the map. With the traditional page-based web model, moving beyond the current map area would require loading a whole new page. AJAX allowed Google Maps to fetch only what it required, when it required it, without interrupting the experience. Tiled rendering provided the pieces, and AJAX made it possible to fetch them without reloading the page.

Direct UI Manipulation

Before Google Maps, most websites were still largely document-based experiences built around clicking links, scrolling pages, and filling in forms. Richer mouse interactions were possible, but they were far from commonplace.

Google Maps changed expectations by combining AJAX, tiled rendering, and direct manipulation. Instead of clicking controls and waiting for a new map to load, users could simply grab the map and drag it around. The mouse wheel could zoom in and out, making the map feel less like a web page and more like a desktop application.

Direct manipulation was not invented by Google, but Google Maps played a major role in popularising it on the web. Similar interactions soon became increasingly common, from dragging items to reorder lists and columns to dropping files directly onto a page for upload.

This was a watershed moment for the web. AJAX made the interface responsive without the need for a page reload, tiled rendering made the map loading efficient, and direct manipulation made the whole thing feel totally natural to a user.

So, what’s the problem?

You may have noticed that all these new frontend architecture patterns rely on one thing… JavaScript. This is where we get to the crux of the matter, and also the blog post! There’s an important question that needs to be answered: what happens to a digital map in a browser when JavaScript isn't available? Well, let’s see how Google Maps handles it:

When JavaScript is manually disabled Google Maps shows the following message: When you have eliminated the JavaScript, whatever remains must be an empty page. Enable JavaScript to see Google Maps.

Looking at the image above, the result really isn’t at all useful for a user, is it?

I recently wrote about Digital Poverty and I had a whole section dedicated to Capability & Literacy. From my research I’d have to guess that a huge proportion of users have no idea what JavaScript is, let alone how to enable or disable it!

In fact, the messaging in this image really bothers me. Progressive Enhancement is far too often framed as being about users enabling or disabling JavaScript, but that largely misses the point and is a red herring.

The average user neither knows nor cares what JavaScript is. However, what they may have is: an unreliable connection, a slow device, limited data, or poor rural connectivity. Progressive Enhancement is there primarily to protect these users when JavaScript fails, not when someone deliberately turns it off.

And there are plenty of reasons JavaScript can fail, as the ⁠GOV.UK Service Manual explains:

  • slow or unreliable network connections
  • JavaScript files failing to download
  • third-party services or CDNs being unavailable
  • browser extensions, ad blockers, or privacy tools blocking scripts
  • antivirus or security software blocking or modifying scripts
  • older or unsupported browsers
  • low-memory devices terminating or failing to execute scripts
  • JavaScript errors preventing part, or all, of the application from running

That last point is critical for inclusive design. A user can have a perfect connection, a modern browser, and JavaScript enabled, yet a simple bug, unexpected API response, or third-party failure can still break JavaScript.

Reducing JavaScript failure to “the user disabled it” is far too simplistic, and, frankly, it really bugs me when that is the only failure case considered!

JavaScript and the Service Manual

This seems like a good time to address something I had to defend and clarify many, many times while working at GDS:

  1. Does GDS hate JavaScript?
  2. Does GDS ban JavaScript?
  3. Can I use JavaScript in my service?
  4. We want to use [insert latest framework here], will it pass a Service Assessment?

These are all variations on the same question about the use of JavaScript in UK government services, and I had to respond to each variation with pretty much the same response:

No, GDS doesn’t hate or ban JavaScript. In fact, you can use as much JavaScript as you like, but (yes, there’s always a but) the critical point is that users must still have an adequate fallback that allows them to complete the task they came to do.

That fallback word is critical. If JavaScript fails and a user is simply greeted with an “Enable JavaScript to use this service” message, the service has failed them.

There’s also a serious risk of the service failing the following points in the Service Standard:

More detail on each of the potential Service Standard failures is provided below:

Point 5: Make sure everyone can use the service

A failure on Point 5 is fairly obvious. A service that solely relies on JavaScript is more likely to exclude users on slow or unstable connections, as well as those using older or resource-constrained devices with limited memory and CPU performance. JavaScript does not need to be deliberately disabled to cause a problem. It can fail to download, time out, or take considerably longer to parse and execute on a lower-powered device.

Point 5 requires teams to “avoid excluding any groups within the audience they’re intended to serve”, including people without reliable internet access. If JavaScript is required to complete the service, connection quality or device capability could become a barrier. Progressive Enhancement reduces this risk by ensuring the core journey works without JavaScript, while JavaScript enhances the experience when it successfully loads and executes.

Point 11: Choose the right tools and technology

Should a service team decide to use a JavaScript-dependent solution, they should be able to demonstrate why it is the right tool for the job. Many government service journeys primarily involve collecting information from users through a sequence of forms, something the web platform already supports natively using only HTML forms and standard HTTP requests. Adding JavaScript should therefore solve a genuine user or service need, rather than simply being the default frontend architectural choice.

This is precisely the kind of decision Point 11 asks teams to justify. Technology should support a high-quality, cost-effective, and inclusive service. If JavaScript introduces additional complexity, dependencies, client-side processing, and potential failure modes, the question should be simple: what does requiring JavaScript allow the user to do that could not be achieved using the simpler capabilities already built into the web platform?

Point 14: Operate a reliable service

Operating a reliable service is not just about achieving high uptime or keeping infrastructure, data, and security standards up to date. Architecture and technology choices also play a critical role.

An unnecessarily complex architecture introduces more dependencies, failure points, and operational overhead, all of which a service team must understand, test, monitor, maintain, and support. That complexity also needs to remain manageable long into the future, often by developers who did not build the original service and may have little knowledge of the codebase or the decisions behind it.

This becomes particularly relevant when a service is dependent on JavaScript. Point 14 requires teams to maximise uptime and speed of response, test effectively, monitor their service, and respond quickly when problems occur. If completing a service depends on JavaScript successfully downloading, parsing, and executing in the user’s browser, this introduces additional client-side failure modes beyond the team’s infrastructure.

Making JavaScript a dependency for a core journey when it is not strictly necessary introduces an additional point of failure. A service that can function without it has fewer dependencies to rely on, making it easier to operate reliably, maintain over time, and demonstrate that reliability in practice.

Back to maps

Although I mentioned earlier in the post that:

Many government service journeys primarily involve collecting information from users through a sequence of forms...

This is an oversimplification. More complex UI components are sometimes needed to help users provide specific information to government, or for government to present complex information, such as through an interactive map.

Below are some government departments and examples of where interactive maps could benefit their users:

Department for Environment, Food & Rural Affairs (Defra)

Example uses for Defra:

  • Flood risk: Help users understand the flood risk associated with a property or area of land, including risks from rivers, the sea, and surface water.
  • Habitats and biodiversity: Allow users to locate habitats and environmentally sensitive areas when planning work, development, land management, or conservation activities.
  • Environmental permitting: Help users identify the location affected by an environmental permit and understand nearby environmental features or constraints.
  • Countryside schemes: Allow farmers and land managers to select land, identify eligible areas, and understand geographic requirements when applying for environmental and countryside schemes.

Ministry of Housing, Communities & Local Government (MHCLG)

Example uses for MHCLG:

  • Development locations: Allow users to locate a proposed development, select the relevant land, and draw or amend a site boundary.
  • Tree Preservation Orders: Identify protected trees and areas covered by Tree Preservation Orders when planning development or changes to a property.
  • Planning applications: Display current and historic planning applications geographically, allowing users to understand proposed development in a particular area.
  • Local authority boundaries: Show which local authority is responsible for a property, development, or area of land, particularly where services and planning policies differ between authorities.

HM Land Registry (HMLR)

Example uses for HMLR:

  • Finding land: Allow users to locate land or property that does not have a conventional postal address, particularly fields, woodland, access roads, and other undeveloped land.
  • Title extents: Display the geographic extent associated with a registered title, helping users understand which land a particular title relates to.
  • Registration status: Allow users to identify whether a particular piece of land is registered with HM Land Registry and locate the relevant registered titles.
  • Rights and interests: Help users locate geographic features associated with a title, such as rights of way, access rights, easements, or other interests affecting the land.

Department for Transport (DfT)

Example uses for DfT:

  • Road networks: Display the road network geographically, including different road classifications and strategically important routes.
  • Transport statistics: Present geographic transport data and statistics, allowing patterns and differences between areas, routes, and transport networks to be explored visually.
  • Infrastructure projects: Display the location and extent of proposed, ongoing, and completed transport infrastructure projects.
  • Traffic flows: Show traffic levels and movement across the road network, helping users understand congestion and how particular routes are being used.

The departments and examples listed above are by no means comprehensive. In fact, I'm certain I’ve hardly scratched the surface of where a maps component could be used across all UK government services. However, even from this small selection, the range of potential uses is clear: from mapping road traffic and identifying Tree Preservation Orders, through to understanding land use and visualising natural hazards such as dangerous flooding across the country.

There’s clearly a user need for a accessible and “GDS compliant” maps component across government. But that raises an interesting question: how does something as complex and interactive as a map work without JavaScript? And perhaps more importantly, how on earth do you progressively enhance a digital map component?

Additionally, what’s the “fallback” for information displayed on a map? I must admit, I’m not quite sure currently, but I intend to do a little digging and suggest a few examples of how it could work.

PE ideas for a map component

For me, this is the difficult part. I’m not a User Researcher or User-centred Designer, I’m a developer. So, what information from a map do you actually need to convey to a user when the interactive map isn’t available?

Well, the first thing I asked myself, simply because I’m a technology-driven developer, was:

Is it possible to render a custom map to a webpage without the use of JavaScript?

If the fallback for an interactive map turns out to be… another map, then I’d say we’re already making progress!

I’m pleased to report that the answer is: yes, it is possible. But, as you might expect, it’s more technically challenging than simply loading a JavaScript component in the browser, pointing it at the Document Object Model (DOM), and letting it do its thing.

The maps component

Before continuing with the blog post, I’d like to briefly introduce you to the maps component I will be experimenting with. This is Defra’s Interactive Map component. I’ve been using it on a client project very recently, and I have to say I’m really impressed with it so far! The team behind it have done some fantastic work, and the fact that it is open-sourced under a MIT licence on GitHub is wonderful to see. It also aligns directly with guidance in the GOV.UK Service manual around Making source code open and reusable, so people like me can use it in their proof of concepts, but more importantly, other government departments can use it in their own services for free, with very little modification required. It already comes with an impressive feature set that is ideal for UK government services.

These features include:

  • accessible keyboard and assistive technology support
  • GOV.UK styled controls and interactions
  • location search with autocomplete
  • selection of locations, areas, and map features
  • support for displaying GeoJSON data
  • responsive behaviour across mobile and desktop devices

It actually comes with a whole lot more features, but I’ve just picked out the top 6 that really stood out to me.

This is the component I’ll be experimenting with. Because it’s already a fairly established component, the hope is that what I learn about progressively enhancing it could help shape a future version, and ultimately benefit government services already using it.

The question now becomes, what does a progressively enhance map component look like? Unfortunately, there isn’t a simple one-size fits all answer to this question. The solution will vary for every service's individual implementation. So let’s start by looking at the fundamentals for all services that use maps.

The fundamentals

Let’s examine the fundamentals of a “fallback page” for a maps component.

The map

So when JavaScript fails, what would we want to show a user? Well, as I mentioned earlier, ideally we’d still show them a map. We already know that’s possible, but there’s an important distinction to make here:

  • With JavaScript available, the user gets an interactive map.
  • Without JavaScript available, the user gets a “plain old” map.

This slight change of requirements is perfectly possible and relatively easy using the web platform. Because, when you strip away all the interactivity, a “plain old” map is really just an image!

Images have been supported by browsers for over three decades. In fact, the first browser to support images was NCSA Mosaic back in 1993. It wasn’t pretty, but it did the job and paved the way for more advanced browsers like Internet Explorer and Netscape Navigator. I won’t go through the full history here, but after 2 browser wars:

We eventually, we arrive in 2026, where the majority of users are using Chromium-based browsers, with smaller pockets using Safari and, sadly for me as a Firefox user, Firefox.

Sorry for the complete tangent! Anyway, where was I? Ah yes, static images of maps…

Thankfully, some of the companies behind JavaScript-driven maps also let you generate a static image of the same map.

For example, Google supply their own Maps Static API, and it provides all the information you get from Google Maps, but rather than rendering separate tiles for the maps it outputs them all as a single image for embedding into a website using a standard <img /> tag.

For the PoC, I’ll be using OpenStreetMap (OSM) , more specifically their OpenStreetMap’s public tile servers.

The plan for the PoC is to use the same coordinates, zoom level, and dimensions for both the interactive JavaScript map and its static image fallback. The key to this technique is generating the static map image on a server then serving it to the browser as you would any other image.

For my PoC I’m going to be using Node, Express, and TypeScript in order to do this, but you can use other backend technologies too including:

So there are plenty of ways to set up this technique, regardless of what technical stack you are already running.

Important note: If you use this technique, make sure you read the OpenStreetMap Tile Usage Policy. OSM data is free to use, but its public tile servers are a shared, donation-funded resource and come with usage restrictions. In this PoC, I cache each rendered static map locally, so the OSM tile servers are only contacted once, when the static map images are first generated.

Should you require more requests or greater map customisation, I’d recommend looking at other dedicated static map providers such as:

As you can see, there are plenty of services to choose from depending on the price and request volume you need.

The information

So, we’ve managed to replace our interactive map with a server-rendered static one. Job done, right? Well, not quite. We still need to consider what the fully interactive map was actually trying to communicate to the user, and whether our static version communicates that too. What that involves depends entirely on the service, so let’s look at an example.

A progressively enhanced flood risk service

One of the examples I mentioned earlier was a…

Flood risk: A service to help users understand the flood risk associated with a property or area of land, including risks from rivers, the sea, and surface water.

So the question is: what additional information does a user need alongside a static map to understand and use the service if JavaScript fails?

For the flood risk example I have listed:

  • Severity: Severe flood warning
  • Risk: High, with danger to life
  • Location: e.g. Bridgnorth Low Town, along the River Severn
  • Affected areas: Roads and locations at risk of flooding
  • Timing: When the warning started and is expected to end
  • Immediate action: Leave if instructed, and call 999 if in danger
  • Safety advice: Avoid flood water, and move vehicles, pets, and important items to higher ground where safe

In doing so, even if JavaScript fails in some way, the user can still see the map and access all the information they need to avoid the affected area and stay safe.

You can see a “live" example of this service from my PoC below:

Other Examples

I’ve actually created several other examples based on the departmental use cases listed above⁠:

Basic Map

A very basic example using the Defra Interactive Map component, progressively enhanced with a static map fallback for when JavaScript fails.

Walking route

A map of the route you’d walk from Buckingham Palace to Westminster Abbey, should you fancy a rather pleasant stroll through central London. It includes a static map and an HTML table with directions to follow as a fallback for the no-JavaScript version of the page.

Planning Appeal

This map shows the appeal site, construction access, nearby facilities, and wildlife along the River Ouse. Use the key to identify each feature. The no-JavaScript fallback also shows the proposed development, roads, wildlife, facilities, and its impact on the beautiful East Sussex town of Lewes.

Tree Preservation Order

This map shows an area covered by Fife Council’s Tree Preservation Order and the five protected trees within it. Use the key to identify the protected area. The no-JavaScript fallback describes the same woodland and trees, their locations, restrictions, and how to report a problem.

Title extent

An example register, including static map, the title number, property, tenure, ownership, area, and registration details. If the map cannot be used, the same information is provided in text, describing the registered land, what is and is not included, and the surrounding area. The registered title is outlined in red, matching the convention used on HM Land Registry title plans.

Road networks

A map of a proposed Birmingham city centre 20mph (ca. 32 km/h) zone, showing roads that would change from 30mph (ca. 48 km/h) to 20mph (ca. 32 km/h) in orange, the A38 Queensway routes that would remain at 30mph (ca. 48 km/h) in blue, and the proposed zone as a shaded area. A list identifies the affected roads and those that would remain unchanged, while a static map with a colour key provides the same information if the interactive map cannot be used.

Countryside schemes

A map of land around Manor Farm, showing which parcels are available for the Sustainable Farming Incentive, land already in an agreement, the River Windrush and its 6-metre buffer, and the nearby Salmonsbury Meadows Site of Special Scientific Interest (SSSI). The page also provides holding details, geographic rules, and a breakdown of eligible and unavailable land, with a static map and colour key available if the interactive map cannot be used.

Local authority boundaries

A map of the local authority boundary around 400 Filton Avenue, showing whether the property falls within South Gloucestershire or Bristol and which council is responsible for local services. The page identifies the property and boundary, provides address and local authority details, and explains which council provides services such as planning, bins, council tax, schools, and highways. A static map and colour key are available if the interactive map cannot be used.

Rights and interests

A map of the land, rights, and interests affecting an property in Castle Combe, showing the registered title boundary, a private right of way, drainage easement, and nearby public footpath. The page also provides title details and explains each right or interest, with a static map and colour key available if the interactive map cannot be used.

Planning applications

A map of current and historic example planning applications across York, showing the search area and applications colour-coded by status, including consultation, under consideration, granted, and refused. A table provides the reference, address, proposal, and status for each application, with a static map, colour key, and text summary available if the interactive map cannot be used.

Transport statistics

A map of bus passenger journeys per person across the 7 West Midlands metropolitan boroughs, with darker shades representing higher numbers of journeys. A table provides the exact figure for each local authority and compares it with the West Midlands average, with a static map, colour key, and text summary available if the interactive map cannot be used.

GDS assessment ready?

I guess the big question after all this experimentation is: will it help a service using a map component pass a ⁠GDS service assessment more easily?

I’d like to think so, or at the very least, it certainly shouldn’t hurt! It demonstrates that the service team has properly considered what happens when JavaScript isn’t available, and, more importantly, whether users can still access the information they need and complete their task.

That being said, a service assessment looks at far more than whether a map works without JavaScript. Assessors consider many different aspects of a service, including:

  • meeting a clear user need
  • being simple and easy to use
  • working for everyone who needs it
  • meeting accessibility standards
  • protecting users’ privacy and security
  • using appropriate technology
  • working across devices and browsers
  • performing well on slow connections
  • providing support when users need it
  • measuring and improving the service
  • operating reliably and sustainably

If I were looking at this from a service assessor’s perspective, however, I can see a few potential concerns with this approach:

  1. Additional cost: generating static maps may introduce additional usage or licensing costs, depending on the provider and the number of maps being generated.
  2. Another third-party dependency: using a separate static map provider introduces another external dependency that the service must rely on, monitor, and potentially replace in the future.
  3. Additional complexity and maintenance: the service team now has two ways of presenting the same information, both of which need to be developed, tested, maintained, and kept consistent over time. This additional work is often an unavoidable part of Progressive Enhancement, where a simpler baseline experience is provided before richer functionality is layered on top.

Summary

This post explored whether an interactive maps component could be progressively enhanced for UK government services, ensuring users could still access the information they needed when JavaScript failed.

Using Defra’s Interactive Map component, I experimented with server-rendered static maps, structured HTML content, tables, directions, and colour keys across real-world government use cases, including flood warnings, planning, land registration, transport, and environmental schemes.

The examples demonstrated that progressive enhancement for maps was not only possible, but could provide a resilient and accessible alternative to a JavaScript-only experience.

While this approach alone will not guarantee passing a GDS service assessment, it could help teams demonstrate that they had considered accessibility, resilience, and the needs of users when JavaScript fails.

Lastly, if you are interested in the code for the PoC, you can find it on GitHub here. And a link to all the example map pages can be found here.

As always, thanks for reading. I hope you enjoyed it as much as I enjoyed writing it. Feedback and corrections are always welcome, so please feel free to let me know!


Post changelog:

  • 20/09/26: Initial post published.

Webmentions

A webmention is a way to notify this site when you've linked to it from your own site.