Progressive Enhancement: Building Sites That Never Fully Break

JavaScript fails more often than you think: flaky connections, ad blockers, browser extensions and CDN outages. Progressive enhancement keeps orders and enquiries flowing when it does. Here is how to layer your site so it degrades gracefully.

JavaScript fails more often than you think

Ask a business owner what a broken website looks like and they will describe a server error page. The more common failure is quieter: the page loads, the branding looks fine, but the JavaScript that powers the menu, the product filters or the checkout button never runs. The visitor sees a site that appears healthy and does nothing.

This happens far more often than most owners realise. When the UK's Government Digital Service measured it on GOV.UK, roughly one visit in a hundred did not run JavaScript, and the vast majority of those visitors had not turned anything off. The script simply failed to arrive or execute. The causes are mundane:

  • A mobile connection dropping a script file mid-download on the train into New Street
  • Ad blockers and privacy extensions blocking bundles that look like tracking code
  • A third-party tag manager or CDN having a bad afternoon
  • Older browsers and locked-down corporate networks choking on modern syntax
  • One unrelated script error halting everything queued to run after it

On a site taking orders or enquiries, every one of those is a silent lost sale. Progressive enhancement is the discipline that turns "nothing works" into "the important things still work".

The three-layer principle

Progressive enhancement means building in three layers, each useful on its own.

  • HTML first: content, links and forms work as plain markup. A visitor can read, navigate and submit with nothing else loaded.
  • CSS second: layout and branding improve the experience, but stripping them still leaves a readable, usable document.
  • JavaScript last: scripts intercept and improve behaviour that already works, rather than being the only way anything happens.

The one-question test: if this script never runs, can a visitor still complete the task? This is not the same as graceful degradation, which builds a JavaScript application first and bolts fallbacks on afterwards. Enhancement starts from a working baseline, so there is nothing to bolt on. Three failure patterns turn up again and again on small-business sites. Here is how each plays out, and the fix.

Need a hand with this?

Our team delivers Web Design for UK businesses — with a free initial consultation, transparent fixed quotes and no lock-in contracts. Tell us what you're working on →

Breakage one: the add-to-basket button that was never a button

A familiar ecommerce pattern: the "Add to basket" control is a styled div with a JavaScript click handler, and the whole basket lives in the browser. One day a marketing tag near the top of the page throws an error, every handler queued behind it never binds, and the button becomes purely decorative. Analytics still record visits, so revenue quietly drops until someone spots the pattern days later.

The fix: make it a real button inside a real form that posts to a server endpoint, which adds the item and returns the basket page. JavaScript then enhances that form, intercepting the submit, updating a mini-cart and keeping the shopper on the page. When the script fails, the browser falls back to the plain form post and the sale still happens. Customers get a slightly old-fashioned experience instead of no experience.

Breakage two: the enquiry form that lived inside a script

Service businesses often embed their contact form from a third-party widget: an empty container that a remote script fills in. Privacy extensions and consent tools block exactly this category of script, so a meaningful slice of visitors sees a blank space where the form should be. Nobody complains. They simply leave and ring a competitor.

The fix: a native HTML form on your own page, with proper labels, posting to your own endpoint or your platform's form handler, validated on the server. JavaScript adds inline validation and an in-page "thanks" message as an upgrade. As a final safety net, print your phone number and email address as plain text near the form, so even a fully broken page still produces enquiries.

Breakage three: the menu that vanished on mobile

A single-location business hides its navigation behind a hamburger icon on mobile, and the icon's behaviour lives in the main script bundle. An update introduces a syntax error, the bundle stops parsing on older phones, and mobile visitors can no longer reach the booking or contact pages at all. On desktop everything looks fine, which is why it goes unnoticed.

The fix: render the navigation as an ordinary list of links that works with nothing else loaded, then let JavaScript collapse it behind the hamburger once it has successfully run. Alternatively, use a CSS-only pattern such as the details and summary elements. The rule of thumb: enhance in the direction of hiding, never in the direction of revealing. If the script dies, visitors should see too much menu, not none.

Key Takeaway

Build every revenue-critical journey (navigation, product pages, forms, checkout) to work as plain HTML first, then let JavaScript improve it. Test by disabling JavaScript in DevTools and attempting to buy or enquire: whatever breaks is costing you money every time a script fails to load, which is more often than you think. Real buttons, real forms and server-rendered content are the cheapest insurance a small-business website can have.

A checklist you can apply this week

You do not need to rebuild your site to benefit. Work through this list on your existing pages:

  • Use real anchor, button and form elements for anything that navigates, triggers or submits
  • Render core content and product information on the server, not only in the browser
  • Load third-party scripts with async or defer so one slow tag cannot block the page
  • Open DevTools, disable JavaScript, and attempt the four journeys that make you money
  • Add error monitoring (Sentry has a free tier) so script failures stop being invisible
  • If you use a JavaScript framework, enable server-side rendering rather than shipping an empty shell

None of this rules out rich interactivity. It simply means the polished version is a bonus layer rather than a single point of failure. If your own JavaScript-off test ends at a dead button, our web team at Thind Global Services can help you rebuild the baseline.

Work With Us

Need Help With Your Digital Strategy?

Our team of experts is ready to help. Get a free consultation and tailored proposal.