Progressive enhancement for both humans and agents
Progressive enhancement has been a web development principle for over twenty years. The idea is simple: start with a baseline that works everywhere, then add features for more capable clients. With AI agents now browsing the web, this principle matters more than ever, because agents are the new baseline client.
Agents are the simplest browser
Think about what an AI agent typically has to work with. Some agents run a full browser with JavaScript. Others parse raw HTML. Some only look at the accessibility tree. The range of capability is wider than the difference between Chrome and Safari.
Progressive enhancement says: build for the least capable client first. That used to mean "works without JavaScript." Now it also means "works for an agent that only reads the HTML source."
The three layers, updated
The classic progressive enhancement layers map neatly to agent capabilities:
Layer 1: HTML (content and structure). This is what every agent can access. Semantic HTML, proper headings, labelled forms, meaningful link text. If your site works at this layer, basic agents can use it.
Layer 2: CSS (presentation). Agents do not care about CSS. They do not see your layout, colours, or animations. But CSS choices affect agents indirectly, because developers sometimes use CSS to convey meaning that should be in HTML. A price shown in red to indicate a sale means nothing to an agent unless the HTML also marks it as a sale price.
Layer 3: JavaScript (behaviour). Full browser agents can execute JavaScript. Headless agents may or may not. API-based agents never will. If a critical action (adding to cart, submitting a form, showing search results) only works with JavaScript, simpler agents are locked out.
What this looks like in practice
Here is a product listing that works at all three layers:
<!-- Layer 1: HTML that works without CSS or JS -->
<article data-component="product-card">
<h2><a href="/products/keyboard">Wireless Keyboard</a></h2>
<p>Compact wireless keyboard with UK layout, Bluetooth connectivity</p>
<p>Price: <span data-field="price">49.99 GBP</span></p>
<p>
<span data-field="stock-status">In stock</span>
(dispatches within 24 hours)
</p>
<!-- Form works without JS via standard form submission -->
<form action="/cart/add" method="post">
<input type="hidden" name="product_id" value="prod_123" />
<label for="qty-prod_123">Quantity</label>
<input type="number" id="qty-prod_123" name="quantity" value="1" min="1" max="10" />
<button type="submit">Add to basket</button>
</form>
</article>
// Layer 3: JS enhancement for richer experience
document.querySelector('form[action="/cart/add"]')
.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const response = await fetch('/api/cart/add', {
method: 'POST',
body: formData,
});
if (response.ok) {
updateCartBadge();
showAddedConfirmation();
}
});
Without JavaScript, the form submits normally and the server handles the cart addition. With JavaScript, the experience is smoother: no page reload, an animated confirmation, a cart badge update. Agents that run JavaScript get the enhanced version. Agents that do not still get a working "add to cart" flow.
Server-side rendering is your friend
Client-side rendering hides content from agents because the server sends an empty <div id="root"> and JavaScript builds the entire page. An agent that does not execute JavaScript sees nothing.
Server-side rendering (SSR) fixes this. The server sends complete HTML that agents can read immediately, while JavaScript takes over in the browser for the interactive experience. Every major framework supports this:
- Next.js: SSR by default for server components
- Nuxt: SSR mode with
ssr: true - SvelteKit: SSR by default
- Remix: SSR by default
If you are building a new application, pick a framework that supports SSR out of the box. If you have an existing SPA, consider adding SSR for key pages that agents need to access (product pages, search results, service information).
Forms deserve special attention
Forms are where progressive enhancement pays the biggest dividends for agents. A form that requires JavaScript to function is completely inaccessible to simpler agents.
The pattern is straightforward:
- Build the form with a standard
actionandmethod - Make sure the server-side handler works for regular form submissions
- Add JavaScript to enhance the experience (AJAX submission, inline validation, animations)
<!-- Works without JS -->
<form action="/contact" method="post">
<label for="name">Name</label>
<input type="text" id="name" name="name" required />
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Send message</button>
</form>
This form works for every agent, every browser, and every user, regardless of JavaScript support. The JavaScript enhancement is additive, not essential.
Navigation that degrades gracefully
Single-page application routing breaks for agents that do not execute JavaScript. Every important page should have a real URL that returns content from the server.
Test this yourself: disable JavaScript in your browser and try to access your key pages. If you see a blank page or a loading spinner, agents without JavaScript see the same thing.
The payoff
Progressive enhancement is not extra work. It is less work in the long run. You build a solid baseline once, then enhance it. When a new type of agent appears with different capabilities, your baseline still works. When JavaScript fails (it does, regularly), your site still works. When a user on a slow connection gets impatient and interacts before scripts load, your site still works.
For agent compatibility specifically, progressive enhancement means you do not need to worry about which agents run JavaScript and which do not. Your HTML layer handles the simpler agents. Your JavaScript layer enhances the experience for agents with full browser capabilities. Both groups can complete their tasks.
Build from the bottom up. Start with HTML that works. Add features on top. That is progressive enhancement, and it is the most practical approach to building for both humans and agents. Audit your site to see how well your baseline holds up.