What Is an MPA — Multi-Page Applications Explained
In this tutorial, you will learn about What Is an MPA. We cover key concepts, practical examples, and best practices to help you master this topic.
A Multi-Page Application (MPA) reloads the entire page from the server on each navigation, with each page having its own URL and the server sending fully-formed HTML for each request.
What You'll Learn
By the end of this tutorial, you will understand what an MPA is, how it differs from an SPA, the request-response cycle, server-side rendering of pages, and the advantages of the traditional web model.
Why It Matters
MPAs power most of the internet — e-commerce, news sites, CMS platforms, and corporate websites. Understanding MPAs is essential because they offer better SEO, simpler architecture, and broader browser compatibility than SPAs. Most web applications start as MPAs.
Real-World Use
Amazon, Wikipedia, and The New York Times are all MPAs. Each product page, article, or category has its own URL. When you click a link, the browser loads a new page from the server. This model has powered the web since its beginning and remains the best choice for content-heavy sites.
How an MPA Works
┌──────────┐ ┌──────────┐
│ Browser │ │ Server │
└────┬─────┘ └────┬─────┘
│ │
│ GET /products │
│────────────────────>│
│ │ Server fetches data,
│ │ renders full HTML
│ │
│ Full HTML page │
│ (status 200) │
│<────────────────────│
│ │
│ Browser renders │
│ new page │
│ (full page reload) │
│ │
│ GET /products/123 │
│────────────────────>│
│ │ New request,
│ │ new HTML page
│ Full HTML page │
│<────────────────────│
│ │
│ Browser renders │
│ new page again │
└─────────────────────┘
Think of an MPA like a book. Each page is a separate piece of paper with its own content. When you turn a page, you see entirely new content. The server is like the printing press that produces each page fresh when you request it. There is no JavaScript framework needed — the server sends what the browser displays.
Server Response in an MPA
<!-- Server returns a complete HTML document for each request -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content="Browse our product catalog with free shipping.">
<title>Product Catalog — My Store</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/products">Products</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
<main>
<h1>Product Catalog</h1>
<div class="products">
<article>
<h2><a href="/products/1">Widget</a></h2>
<p>$9.99</p>
</article>
<article>
<h2><a href="/products/2">Gadget</a></h2>
<p>$19.99</p>
</article>
</div>
</main>
<footer>
<p>© 2026 My Store</p>
</footer>
</body>
</html>
Page Navigation in an MPA
// Traditional MPA navigation — browser handles everything
// When user clicks a link, browser:
// 1. Cancels current page rendering
// 2. Shows loading spinner
// 3. Requests new HTML from server
// 4. Receives complete HTML document
// 5. Parses and renders the new page
// 6. Updates the URL in the address bar
// You can enhance navigation with JavaScript
// but the default behavior works without any JS
document.addEventListener('DOMContentLoaded', () => {
console.log('Page loaded at:', new Date().toISOString());
console.log('Page URL:', window.location.href);
console.log('Page title:', document.title);
});
// Server-side redirect example
// In Express.js:
app.get('/old-page', (req, res) => {
res.redirect(301, '/new-page');
});
// Each page has its own lifecycle:
// "Page 1 loaded at: 2026-06-28T10:00:00.000Z"
// "Page 1 URL: https://example.com/products"
// "Page 1 title: Product Catalog — My Store"
// — User clicks link —
// "Page 2 loaded at: 2026-06-28T10:00:02.500Z"
// "Page 2 URL: https://example.com/products/1"
// "Page 2 title: Widget — My Store"
Common Mistakes
- Adding unnecessary JavaScript frameworks to MPAs. MPAs do not need React or Vue. Server-rendered HTML with minimal JavaScript is the MPA philosophy. Only add JS where interactivity is required.
- Duplicating code across pages. Each page is a separate server response, so shared components (header, footer, navigation) must be rendered on the server. Use template inheritance or partials.
- Blocking rendering with large CSS/JS. Unlike SPAs where JS blocks rendering, in MPAs CSS blocks rendering. Inline critical CSS and defer non-critical stylesheets.
- Not leveraging browser Caching. Since each page load is a full request, caching is critical for MPA performance. Set Cache-Control headers for static assets and leverage ETags.
- Treating MPAs as outdated. MPAs are not old-fashioned — they are the right tool for content-focused sites. Choosing MPA over SPA is an architectural decision, not a technology choice.
Practice Questions
- What happens in the browser when a user clicks a link in an MPA?
- How does the server generate HTML in an MPA?
- What are the advantages of MPAs over SPAs for content-heavy websites?
- Why do MPAs not require client-side routing libraries?
- How does browser caching benefit MPA performance?
Challenge: Build a simple MPA with a home page, about page, and contact page using Express.js"Express" >}}.js or any server-side framework. Each page should be a complete HTML document served from the server. Measure the time it takes to navigate between pages and compare it to a client-side routed SPA.
FAQ
Mini Project
Build a 5-page MPA using your preferred server-side technology. Include: a home page with featured content, a blog listing page, a blog post detail page, an about page, and a contact page with a form. Each page must be a complete HTML document served from the server. Add server-side includes or template inheritance to avoid duplicating the header and footer.
What's Next
You understand what an MPA is. Now compare it with MPAs vs SPAs to understand when to choose each architecture.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro