Introduction

In the previous article, we saw how AJAX and jQuery transformed the web from a static, request-response model into something far more dynamic and interactive.

But as applications became more complex, the patchwork of jQuery plugins, imperative DOM manipulation, and scattered logic began to collapse under its own weight.

We needed more than snippets — we needed structure.

And that’s when Single Page Applications (SPAs) emerged.


What Is a Single Page Application?

A Single Page Application is a web app that:

  • Loads a single HTML page initially
  • Uses JavaScript to manage routing, rendering, and data updates
  • Interacts with the server via APIs (typically JSON over HTTP)
  • Avoids full-page reloads entirely

In SPAs, the browser becomes the runtime — not just the display layer.


The Core Shift

Here’s how responsibilities changed from the server to the browser:

Responsibility Pre-SPA (AJAX/jQuery) SPA Era
Routing Server-side Browser (client-side)
Rendering Mostly server Fully in browser
State Management Minimal (forms, DOM) Managed in JS memory
Data Fetching AJAX via jQuery Fetch/XHR, usually via libraries like Axios
UI Feedback jQuery-driven Built into components and state transitions

The entire application now lived in the frontend.


What Changed in the Developer Experience?

SPAs came with JavaScript frameworks that introduced powerful new ideas:

Components

UI broken into small, reusable pieces with their own logic and state.

Virtual DOM & Declarative Rendering

Instead of manually changing the DOM, you define what the UI should look like, and the framework figures out how to update it.

Client-Side Routing

No more page reloads — frameworks like React Router handled in-browser navigation via the History API.

Frontend State Management

Libraries like Redux and Vuex managed complex client-side state and behavior.


Too Much jQuery → A Flood of Frameworks

jQuery gave us power — but it didn’t scale well for large apps.

Developers were:

  • Manually selecting DOM elements
  • Mutating UI based on state
  • Writing spaghetti code with callbacks and inline logic

This chaos created a need for structure. And that sparked an explosion of libraries and frameworks:

  • Backbone.js – gave structure to models, views, and routers
  • Knockout.js – introduced declarative bindings with data-bind
  • AngularJS – provided two-way data binding and full app structure
  • React – focused on component composition and one-way data flow
  • Vue – blended simplicity with structure, quickly rising in popularity

All of these were answers to the same problem: “jQuery is powerful, but we need more discipline.”


Real-World Example: A Dashboard

In the SPA world, a dashboard doesn’t reload — it updates live:

  • Clicking sidebar links doesn’t reload the page
  • Data is fetched in the background and rendered instantly
  • Modals, dropdowns, and forms all live in memory
  • Entire layouts are reused and dynamically changed

Users now expect this level of smoothness by default.


But There Were Tradeoffs

Validation Became a Shared Responsibility

In traditional server-rendered apps, validation happened only on the backend. If you submitted a form with an invalid email or empty field, the server would reject it and send back an error.

In SPAs, users expected instant feedback.

That meant:

  • The frontend had to validate inputs before submission (for speed and UX)
  • The backend still needed to validate data (for security and correctness)

So now, validation logic was duplicated — in two different languages (JavaScript and PHP/Node/etc.). This made development more complex and error-prone, especially for teams trying to stay consistent.

SEO Suffered — And We Tried to Fix It

One of the biggest drawbacks of SPAs was SEO.

Traditional multi-page apps rendered HTML on the server, which search engines could easily crawl and index. But SPAs loaded a bare <div id="app"> and relied on JavaScript to build the UI — meaning crawlers saw an empty page.

This was a major problem for:

  • Blogs
  • Marketing sites
  • E-commerce platforms
  • Any public content that needed discoverability

Attempts to Solve It

To fix SEO in SPAs, developers tried several workarounds:

  1. Pre-rendering / Static Generation For pages that don’t change often (like landing pages), tools like prerender.io, Gatsby, or Next.js's static generation would output plain HTML at build time.
  2. Server-Side Rendering (SSR) Frameworks like Next.js (React), Nuxt.js (Vue), and Angular Universal allowed JavaScript apps to run on the server and return fully-rendered HTML to bots and users alike.
  3. Hydration After SSR or static generation, the frontend JS "hydrates" the page — attaching event listeners and reactivating interactivity. This gave the best of both worlds: SEO-ready HTML and dynamic UI.
  4. Dynamic Rendering for Bots Some teams set up logic to detect bots and serve them pre-rendered HTML, while serving SPAs to real users. This was hacky and error-prone, but sometimes necessary.

While these strategies helped, they added complexity, tooling overhead, and often performance issues. It became clear that SPAs weren’t always the right default — especially for content-first sites.

Backend Was Reduced to APIs

As the frontend took on more responsibility — rendering, routing, state, validation — the backend was pushed into the background.

Its new role:

  • Serve static files (index.html, JS bundles)
  • Provide RESTful APIs or GraphQL endpoints
  • Handle authentication, data persistence, and server-side validation

The backend was no longer controlling the user experience — it was simply a data provider.

This shift birthed terms like:

  • “Headless backend”
  • “API-first architecture”
  • “Frontend-heavy apps”

Why This Phase Matters

SPAs represent the peak of frontend-centric architecture. For nearly a decade, “modern web development” meant:

  • Build everything in JavaScript
  • Talk to APIs
  • Ship bundles
  • Hydrate the DOM

This mindset dominated tooling, frameworks, hiring, and user experience.

But now, the industry is shifting again — toward rebalancing responsibilities, improving performance, and rediscovering the power of HTML-first rendering.


Summary

SPAs changed the game by:

  • Bringing full routing and rendering to the browser
  • Making JavaScript the center of the web experience
  • Ushering in a new era of frontend frameworks

But with that power came new problems — and that’s what set the stage for the next transition.

In Part 4, we’ll look at where the web is headed now — with server-first rendering, resumability, and a renewed focus on simplicity and speed.


If you found this post helpful, consider supporting my work — it means a lot.

 Raheel Shan | Support my work
Raheel Shan | Support my work
Support my work
raheelshan.com
Comments


Comment created and will be displayed once approved.