Page transitions are not a reason to become an SPA
For years, the pitch for turning a content site into a single-page app included a line about smooth page transitions. The View Transitions API removes that line. A Next.js App Router site, or a mostly static marketing site, can crossfade between routes without owning a client navigation stack. The useful move is to treat that as progressive enhancement and leave the architecture alone.
What the SPA pitch was actually buying
The honest version of the SPA argument for marketing and content sites was never about data fetching. It was about continuity: the header does not flash, the hero does not pop, the scroll position does not feel like a hard cut. Teams paid for that continuity with a client router, hydration cost, loading states that had to be invented, and a second set of bugs that only appear after JavaScript runs.
On the sites we ship — Provale Cup, studio partner marketing builds, our own site — most navigations are document to document. The content is in the HTML. The animation layer, when we had one, sat on top of that with framer-motion or CSS. The page did not need to become an application to feel less abrupt.
What was missing was a browser-native way to bridge two documents. That is what cross-document view transitions are for. The pitch that used to force an SPA decision is now a CSS concern.
What view transitions give you without the rewrite
Same-document transitions cover in-page state changes: a list that filters, a detail that expands, a step that advances. You wrap the DOM update in document.startViewTransition, the browser snapshots old and new, and CSS controls the animation. If the API is missing, you run the same update with no animation. The feature detection is one branch, not a parallel architecture.
Cross-document transitions cover real navigations. Opt in with the @view-transition at-rule on both pages, optionally name persistent elements like a logo or shared card, and the browser handles the bridge. Unsupported browsers navigate normally. There is no client router to maintain and no loading skeleton required for the enhancement path.
That is the important property. The site that works without the transition is the product. The transition is optional paint on top of a navigation that already succeeded.
Progressive enhancement, not a feature to demo
The failure mode we have seen, and pushed back on, is treating view transitions as the reason for the next frontend rewrite. A stakeholder watches a demo of a named element morphing from a tile into a detail page and asks why the current site cannot do that. The answer is usually that it can — with a few lines of CSS — and that the morph is not what makes the site good.
We use the same filter we use for motion elsewhere. Does the page remain correct with no transition? Is the first paint still the truth? Does reduced motion get a real branch, not an undefined animation state? If those answers are no, the transition work is premature.
Content sites get the most from a short global crossfade and one or two named elements that survive the navigation. Everything beyond that is choreography. Choreography has a cost in review, in QA, and in the next person who has to name a new shared element without breaking the old ones.
Naming everything is how you make it fragile
view-transition-name is powerful and easy to overuse. Every named element becomes a contract between two routes: both must render something with that name, at a size and position that make the interpolation look intentional. Miss one side and you get a transition that advertises a bug.
On a CMS-driven collage or a project index, that contract is especially sharp. Tile positions come from content. Editors change order. A named transition that assumed tile-3 would still be the third card is now animating the wrong project into the detail view, which is worse than a hard cut.
Our default is sparse naming: the root document, maybe the brand mark, maybe a single hero that truly is the same object on both sides. Lists, cards, and CMS-driven grids stay unnamed until there is a specific navigation that benefits from continuity and a test that proves both sides still match.
Reduced motion still wins
We have already shipped a bug where a reduced-motion branch left the largest heading on a page invisible. View transitions do not excuse repeating that. prefers-reduced-motion: reduce should disable or severely shorten transitions, including cross-document ones. The navigation must complete either way.
This is also where SPA rewrite pressure comes back wearing different clothes. A team that has invested in a client transition layer often treats reduced motion as a theme toggle. A CSS view transition treated as progressive enhancement makes the correct path simpler: if motion is reduced, skip the enhancement and navigate.
If your transition is load-bearing — if the user cannot tell where they are without watching the morph — the design is wrong. Continuity should clarify a navigation that already makes sense in a screenshot of either page.
When you still want a client layer
View transitions do not retire every animation library. Shared-element theater across many simultaneous elements, gesture-driven dismissals, scroll-linked storytelling, and interactions that must run while the route stays put still need intentional motion code. BuilderHelp’s product UI and Endeo’s capture surfaces are not marketing page navigations, and we do not pretend a crossfade solves them.
The distinction is the job. If the job is “make route changes feel less abrupt on a content site,” reach for the platform. If the job is “orchestrate a stateful surface the user is working inside,” keep the library and the tests that go with it.
What we refuse is the middle path: rewriting a document site into a client-routed app primarily so page changes can animate. That used to be a defensible trade. In 2026 it is usually an expensive way to avoid three rules of CSS.