Keeping a Website Usable When JavaScript Fails
JavaScript can fail because of a bug, blocked request, broken CDN, extension, network problem, or third-party script. The useful question is not whether that can happen. It is what the visitor gets when it does.
For a content page, navigation, headings, text, images, links, and contact information should usually remain. A gallery effect may disappear. The article should not.
Send content as content
This page already has something to render:
<article>
<h1>My article</h1>
<p>The article is already in the HTML.</p>
</article>
This one depends on a successful script before it says anything:
<div id="app"></div>
<script src="/app.js"></script>
That architecture can be right for an application. For an article, I would send the article.
An external dependency adds more failure points:
<script src="https://cdn.example.com/app.js"></script>
The CDN, DNS, connection, request policy, or file can fail while your server remains healthy. A downloaded script can also stop on a runtime error:
const user = undefined;
console.log(user.name);
Use real links and forms underneath enhancements
Do not use a button merely to navigate:
<button onclick="goToContact()">Contact</button>
Use the element with a destination:
<a href="/contact/">Contact</a>
A form can submit without client-side code:
<form action="/contact/" method="post">
<input name="email" type="email" required>
<button type="submit">Send</button>
</form>
JavaScript can add inline validation or asynchronous submission later. The basic action still exists.
Native controls provide a useful baseline too. <details> handles a simple disclosure, and a real <button> already has focus and keyboard behaviour.
Let JavaScript improve a working page
Progressive enhancement is a simple order:
HTML → working purpose
CSS → layout and presentation
JavaScript → extra behaviour
Some products genuinely require JavaScript: an image editor, game, or collaborative tool has no meaningful script-free equivalent. Say so honestly:
<noscript>
This tool requires JavaScript to run.
</noscript>
Where possible, give a useful alternative rather than blaming the visitor.
Test partial failure as well as disabling all scripts. An embed, map, analytics request, or chat widget may fail independently. It should not take the surrounding article with it.
For each script, ask what disappears if that one request fails. “The optional animation” is a healthy answer. “The entire article” needs a very good reason. For most content pages, the best fallback is simply honest HTML.
Enjoyed reading this?
If you found this article helpful, consider supporting my writing. Every little bit helps keep this blog going.
Related articles
- How Much JavaScript Does a Website Really Need?
Start with the page's job, use the browser's native features, and add JavaScript only where its behaviour justifies the cost.
- Building a modal with HTML dialog
Build modal windows from the native HTML dialog element, including backdrops, forms, Escape handling, and practical examples.
- Native HTML and CSS Features That Replaced JavaScript
Replace common JavaScript components with native HTML and CSS, from disclosures and dialogs to container queries and scroll effects.