Hybrid Rendering, Headless CMS, and PWAs: Combining Three Web Trends in One App

Hybrid rendering, headless CMS architectures, and Progressive Web Apps are usually treated as separate trends in modern web development. This post summarizes a bachelor thesis that asks whether they can instead be meaningfully combined, and tests that question by building MovieRec, a movie discovery platform using Next.js and Strapi.

Every few years, web development produces a new batch of buzzwords that sound interchangeable in a meeting room but mean very different things to the person actually implementing them. "Let's use a headless CMS, they're trendy right now" is the kind of sentence that sounds reasonable coming from a project lead and slightly terrifying coming from someone who has never had to build the frontend that now has to fetch, cache, and render that content itself.

This article is about three of those trends, taken seriously rather than as buzzwords: hybrid rendering, headless content management, and Progressive Web Apps. The underlying thesis project didn't just study them individually, it asked whether they could be combined into a single, coherent application, and then built one to find out. That application is MovieRec, a film discovery platform, and it's a genuinely useful case study for anyone deciding how to structure a modern web project.

Rendering Is Not One Decision, It's Several

The most fundamental question a frontend has to answer is deceptively simple: where does the HTML actually get built? For a long time, the honest answer was "on the server, always," using something like PHP. Then single-page frameworks like React, Vue, and Angular shifted that work into the browser, and for a while, client-side rendering felt like the obvious default.

It isn't, and the tradeoffs are worth being precise about. With client-side rendering (CSR), the server sends a nearly empty HTML shell along with a JavaScript bundle, and the browser does all the work of fetching data and building the page. This makes for snappy, app-like navigation once everything is loaded, and it takes real load off the server. But that "once everything is loaded" clause matters: on a slow connection, the user stares at a blank screen while scripts download and execute, and search engine crawlers historically struggled to index content that only exists after JavaScript runs.

Server-side rendering (SSR) flips that around. On every request, the server fetches the needed data, builds the full HTML page, and sends something already complete to the browser. Search engines have no trouble with this, since the content is there from the first byte, and users see something meaningful immediately instead of a loading spinner. The cost shows up under load: every single request triggers server-side work, which means more infrastructure, more computing cost, and noticeably higher latency than serving something pre-built.

Static site generation (SSG) sidesteps that entirely by doing the rendering work once, at build time, rather than per request. The resulting HTML files can be hosted on a CDN and served instantly, with essentially zero server load and excellent SEO, since content is present before the page ever reaches the browser. The catch is staleness: the page stays exactly as it was generated until the next full rebuild, which makes SSG a poor fit for content that changes often, and can turn the build process itself into a bottleneck once a site has thousands of pages.

That last problem is exactly what incremental static regeneration (ISR) exists to solve. Instead of rebuilding the entire site whenever anything changes, ISR lets individual pages regenerate on a defined interval, say every ten minutes, without triggering a full rebuild. The first visitor after that interval still gets the previous (slightly outdated) version while the page quietly regenerates in the background for everyone after them. It's a genuinely clever middle ground for large sites like online stores, though it's overkill for a five-page portfolio and not quite fast enough for something like a live news feed, where SSR remains the better fit.

The practical takeaway, and the one the thesis leans on throughout, is that none of these approaches is universally "correct." A modern framework like Next.js doesn't force a single choice for an entire application. It lets different pages within the same app use different rendering strategies, matched to how static or dynamic each page's content actually is. That's the real meaning of "hybrid rendering," and it turns out to be less about picking a winner and more about routing the right tool to the right page.

Headless CMS: Separating Content from Presentation

Traditional content management systems, WordPress being the obvious example, bundle everything together: the admin interface where editors write content, the database where it's stored, and the frontend that renders it for visitors, all coupled into one monolithic system. That bundling is exactly why traditional CMS platforms are easy to set up (install one thing, get a working website), and exactly why they get awkward the moment you need that same content somewhere else, like a mobile app, a smartwatch interface, or a kiosk display.

A headless CMS solves this by cutting the presentation layer off entirely, hence "headless." What's left is a content editing interface and a database, exposed through an API. The frontend becomes a separate concern entirely, built with whatever framework fits the project, and pulling content from the CMS purely through interface calls rather than direct database coupling. The same stored content can then feed a website, a native app, and a smart TV interface simultaneously, from one source of truth.

This decoupling isn't free. It shifts real complexity onto the development side: someone still has to build that separate frontend, which means more infrastructure and more specialized skills than a "download a theme, add some plugins" traditional CMS setup requires. Editors also lose something in the process, namely the live visual preview that comes standard with a tightly coupled system, since the CMS itself has no idea what the final rendered page will look like. In exchange, teams get real architectural flexibility, better scalability (a frontend outage doesn't take down content management, and vice versa), and a smaller attack surface, since a single API endpoint exposes far less than an entire coupled web application.

Neither model is obsolete. Traditional CMS platforms remain the pragmatic choice for a simple blog or small business site where one frontend is genuinely all that's needed. Headless architectures earn their added complexity specifically when a project needs to reach more than one platform, or when it needs a level of frontend flexibility that a monolithic system simply can't offer.

Progressive Web Apps: The Middle Ground Nobody Expected to Work This Well

Native apps have real advantages: full access to device hardware, tight integration with an operating system's design language, and the ability to work reliably without any internet connection at all. They also come with real costs, namely separate codebases for iOS and Android, a slower and more expensive development process, and a 30 percent cut for whichever app store is doing the distributing.

Progressive Web Apps, first articulated by Google's Alex Russell in 2015, are an attempt to close that gap using only the tools browsers already provide. A PWA is fundamentally still a normal website built with HTML, CSS, and JavaScript, but one that meets a specific set of criteria that let it behave like a native app once a user chooses to install it. Discoverable through the same search engines as any other page. Installable to a home screen or app switcher via a small JSON configuration file called the Web App Manifest, which defines the app's name, icons, and color scheme. Reliable even offline, thanks to a Service Worker, a piece of JavaScript that runs independently of any open browser tab and can intercept network requests, serving cached content when connectivity drops out and pushing notifications even while the app itself is closed.

None of this requires learning a new programming language or maintaining two separate codebases. It requires meeting a checklist of properties (responsive, installable, linkable, safe over HTTPS, and connectivity-independent, among others) using web technology that already exists. That's precisely why PWAs are interesting for smaller teams: the incremental cost of adding native-app-like features to an existing web project is genuinely modest compared to building and maintaining a second, fully native app.

The Project: MovieRec

Theory only goes so far, so the thesis put all three concepts to a practical test by designing and building MovieRec, a film discovery platform. Before settling on the feature set, the project looked at three existing competitors: IMDb, with its enormous but somewhat dated catalog and account-gated features; Rotten Tomatoes, whose curated critic scoring is powerful but whose interface feels increasingly cluttered; and Letterboxd, a more modern, social-first take on film logging with the cleanest UI of the three, plus native apps on both major platforms.

The resulting requirements combined the strongest ideas from all three: a searchable, filterable movie overview; detailed per-film pages with cast, director, and release information; persistent user accounts with validated, HTTPS-secured registration; the ability to rate and comment on films, with an aggregated average score per title; a social feed showing other users' reviews and activity; a light and dark mode; SEO-friendly pages; fast load times through a mix of server-side and static rendering; and, tying the whole thing together, installability as a PWA.

The Stack Behind It

On the frontend, React provided the component model, extended by Next.js to add multi-page routing and, crucially, the ability to choose per-page rendering strategies (SSR, SSG, and ISR, alongside plain CSR where it made sense). Styling used SASS rather than plain CSS, mainly for the variable system and better file organization across a project of this size, compiled down to standard CSS automatically as part of Next.js's build process. A handful of focused libraries rounded things out: React Query for efficient, cached data fetching (used heavily for the search and filter functionality), React Hook Form for validation, Nookies for cookie handling around login sessions, next-themes for the dark/light mode toggle, next-seo for search engine metadata, and next-pwa, which handles Service Worker registration without requiring it to be written by hand.

On the backend, Strapi served as the headless CMS, managing everything from film metadata to user-generated lists and reviews, exposed to the Next.js frontend purely through its REST API. For the database layer, Strapi's default option, SQLite, was used directly rather than swapped out, since it ships preconfigured with the CMS and needed no separate setup for a project of this scale.

Rendering in Practice, Not Just in Theory

What makes MovieRec a genuinely useful case study is that it doesn't apply one rendering strategy uniformly. The main movie overview page is server-side rendered: Next.js's getServerSideProps function fetches the full list of films from Strapi's /movies endpoint on every request, so the page is always current and fully indexable by search engines the moment it loads. The individual movie detail pages work differently: since a given film's plot, director, and release date rarely change after being added, those pages are statically generated ahead of time using dynamic routes (a [slug].js file), trading a small amount of build-time work for essentially instant page loads afterward. Ratings, which change constantly as users submit reviews, are rendered client-side instead, since the freshness there matters more than initial load speed, and the personalized activity feed uses server-side rendering again, for the same reason the overview page does.

Search and filtering on the movie overview page relies on React Query rather than a full page reload: as a user types into the search field or picks a genre from a dropdown, the corresponding state updates trigger a fresh API request to Strapi, and only the movie list component re-renders with the results, keeping the interaction fast and avoiding unnecessary full-page fetches.

What It Adds Up To

The combination of a headless CMS and a hybrid-rendering frontend framework turned out to complement each other well, specifically because Strapi's REST API and Next.js's getServerSideProps/getStaticProps functions integrate with almost no friction: fetching JSON data and deciding whether that fetch happens at build time or per request is a matter of choosing the right function, not architecting a custom data layer. A monolithic CMS like WordPress would have made several of MovieRec's more specific features, the dark mode toggle, the dynamic routing for static detail pages, the layered rating and review system, considerably harder to implement cleanly, precisely because everything in that model has to route through one tightly coupled frontend.

Progressive Web App features layered on top with comparatively little effort too. Because the heavy lifting of Service Worker registration is handled by an existing package rather than written from scratch, upgrading an already-functional web app into something installable, with offline fallback behavior, turned out to be a relatively small addition on top of an app that was already working well as a normal website. This particular combination of technologies also turns out to have a natural audience: it's a strong fit for smaller teams or early-stage startups, who get most of the flexibility and multi-platform reach of a fully native, headless-first architecture, without the staffing or budget that a separate native app for each platform would otherwise require.

None of this was without its rough edges. GraphQL would have offered a more efficient way to query filtered data than Strapi's REST API, particularly at a larger scale of users or stored films, but learning an additional query language on top of everything else wasn't worth the tradeoff for a project of this size. That's a reasonable, honest limitation, and probably true of most real projects: the "technically superior" option and the option that fits the time available aren't always the same one.

Looking Forward

Web development doesn't sit still long enough for confident five-year predictions, and the thesis doesn't pretend to make one. What does seem fairly safe to say: the JAMStack's serverless, API-first approach is only becoming more common, and headless CMS platforms fit naturally into that direction as content increasingly needs to reach more than just a single website. Traditional CMS platforms aren't going anywhere either, WordPress isn't losing its dominant market position overnight, but the decoupled alternatives are likely to keep gaining ground as more devices beyond the browser expect to consume the same content. Progressive Web Apps occupy a more uncertain spot: genuinely useful and increasingly capable since 2015, but not yet a full replacement for native apps, a trajectory that depends heavily on how much Apple, in particular, decides to invest in supporting them going forward.

All Articles