There is something you can still do on most websites today.
You can right-click and choose "View Source."
Try it. What you will usually find is not the thing you are looking at.
The content on screen (the data, the meaning, the substance of the page) is often absent from the HTML entirely. Instead, you see a shell: a small scaffold of markup, a handful of empty containers, and JavaScript bundles whose job is to fetch the real content from somewhere else and assemble the page at runtime.
That gap, between what is rendered and what is present in the document, is where the web started to break.
Documents and interfaces
The original web was built from documents.
A document is not just a visual layout. It carries meaning in context. A date in a document is not merely a value; it exists alongside surrounding text that explains what it signifies. The meaning lives with the data.
A user interface, by contrast, is primarily a mechanism for display and interaction. A date in a UI is often just a value populated into a field. Its meaning exists elsewhere: in application code, in a database schema, in the head of the developer who built it.
The early web blurred these ideas productively. HTML documents contained both content and structure. If you could see the page, you could inspect it. If you could inspect it, you could understand it. You could learn from it.
"View Source" was not a debugging tool. It was a guarantee.
The early architecture
At the beginning, servers mostly served static files. Browsers rendered them. Interactivity meant clicking links and loading new documents.
Then servers became programmable. CGI scripts, later PHP and ASP, allowed HTML to be generated dynamically from databases. This mattered, but the browser still received a complete document. Even if the HTML was assembled on the server, the unit of meaning remained intact. You could view the source and see the content. Messy, perhaps, but inspectable.
The web was also learning to separate concerns. CSS split presentation from structure. Templates separated layout from data. But critically, these separations collapsed back into HTML before the document reached the user.
The document remained the consumable unit.
The inflection point
The real shift arrived around the turn of the millennium with XMLHttpRequest.
For the first time, a browser could make HTTP requests outside the document lifecycle. Data could be fetched independently of navigation. Pages could update without reloading. By the middle of the decade, this capability had a name: AJAX.
Initially, it was an optimisation. Why reload an entire document to update a small fragment? Why resend the same navigation chrome repeatedly?
Then it became something more. Developers realised they could build experiences that felt like applications, with Google Maps being the canonical example. Smooth, responsive, stateful. The web could finally compete with native software.
This was genuinely valuable. The problems that AJAX solved were real. Users wanted richer interactions. Developers wanted to build them. The document model, for all its virtues, was limiting.
The trade that followed
By the early 2010s, a new pattern had become dominant:
Serve a minimal HTML document. Load a JavaScript application. Fetch data from APIs. Populate the UI at runtime.
The frameworks that emerged to support this (React, Angular, Vue) were not mistakes. They solved genuine problems: complex state management, component reuse, team coordination at scale. They made certain classes of application possible that would have been nightmarish to build otherwise.
But they also completed a transformation in how we think about web pages.
A typical modern page source now looks like this:
<!doctype html>
<html>
<head>
<title>Dashboard</title>
<script src="/bundle.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Everything the user actually sees (their messages, their documents, their data) is fetched after the fact and injected into that empty <div>.
The HTML document no longer carries meaning. It is a container. The content arrives later, as data. The structure is imposed by code. The semantics live somewhere else.
What was lost
This is the moment the web stopped being natively inspectable.
We can no longer read a page as a document. We can only consume it as an opaque application. The thing you see as a user bears no obvious relationship to the thing that was sent. Even as a developer, you have to follow the program logic. Understanding requires execution.
Even when server-side rendering is used, the underlying model often remains unchanged. Data lives behind APIs. The document is a delivery mechanism, not a source of truth.
For machines, whether search engines or AI systems, the modern web increasingly resembles a black box. To understand a page, an automated system must execute JavaScript, simulate interaction, track state changes, observe side effects. Search engines have had to become headless browsers. Scraping has become browser automation.
The web did not start this way. HTML was always structured. It was always addressable. It was, in a sense, already a kind of database: a tree you could query, a graph you could traverse.
We just stopped treating it that way.
The shape of the problem
None of this happened because developers were careless. It happened because the platform made it possible, and because the trade-offs were attractive at each step. Rich interactions. Fewer full reloads. Shared APIs across clients. Cleaner separation of concerns.
But as we built the web of today, we didn't just add new layers. We hollowed out the document. It stopped carrying content and meaning. It became a bootloader for software.
The web began as a system of meaningful, inspectable, linked documents. Along the way, we've decided that data belonged somewhere else, that meaning could be reconstructed at runtime, that execution was a prerequisite for understanding.
We have gained power. We have also lost something.
In Part 2, I'll look at what that loss actually costs us.