Writing ·

How SSR + Stripe Cut Cart Abandonment 30%

By Sovaid Shah, Software Architect · Next.js · Stripe · SSR · Performance · E-commerce

TL;DR: On Cercle, a Next.js + Rails rental marketplace, cart abandonment fell 30% and time-to-interactive improved 20% after three changes: server-rendering product and category routes, cutting the Stripe checkout path to fewer steps, and lazy-loading heavy UI so the pay button was usable sooner. Checkout speed and trust beat clever UI.

Cercle is a clothing rental and resale marketplace. I worked on it as a full-stack engineer from August 2021 to December 2022, on a Next.js frontend talking to a Rails 6 API, with Stripe for payments.

Two numbers came out of that work: cart abandonment dropped 30% and time-to-interactive improved 20%. This post is about why those two numbers are connected, and what I’d copy onto any marketplace today.

Why do shoppers abandon carts on marketplaces?

Most abandonment advice is about surprise shipping costs and forced account creation. Those matter. But on a marketplace built as a client-heavy React app, there’s a quieter cause: the page looks ready before it is ready.

The shopper taps “Rent” or “Pay”. Nothing happens, because the JavaScript bundle is still parsing on a mid-range phone. They tap again. Maybe it double-submits, maybe it doesn’t. Either way, trust drops right at the moment you’re asking for a card number.

So we treated checkout as a performance problem first and a UX problem second.

What we changed

1. Server-render the routes that sell

Product and category pages were moved to server rendering. That did two jobs at once:

  • Search engines got real HTML for every product and category, instead of an empty shell waiting on client-side fetches.
  • Shoppers saw real content on first paint, so the path from landing to “add to cart” didn’t start with a spinner.

SSR isn’t free. It moves work to the server, and it only pays off on pages where first paint and crawlability matter. For a marketplace, that’s product and category pages. Account settings can stay client-rendered and nobody will notice.

2. Shorten the Stripe checkout path

We wired Stripe into a tighter checkout path with fewer steps between cart and confirmation. The principle: every extra screen between “I want this” and “paid” is a place to leave.

If I were building this today, the checklist would be:

  • Use Stripe’s hosted Checkout or the Payment Element, so card entry, wallets (Apple Pay, Google Pay) and Link autofill come for free instead of being custom-built.
  • Show the full price, including fees and deposits, before the payment step. Rental marketplaces get punished hard for late surprises here.
  • Confirm orders from the checkout.session.completed (or payment_intent.succeeded) webhook, not from the browser redirect. The redirect can fail; the webhook gets retried.
  • Send an idempotency key with payment requests, so a double tap never charges twice.

3. Ship less JavaScript before the pay button

This is where the 20% time-to-interactive gain came from. Heavy UI (image galleries, filters, modals that most shoppers never open) was split out with dynamic imports and loaded only when needed. Data that didn’t change per request was cached instead of recomputed.

The result: the checkout button responded to the first tap more often. That’s hard to show in a screenshot, but it shows up in the abandonment curve.

Why performance and abandonment moved together

They’re the same problem seen from two sides. A slow interactive page loses trust, and checkout is where trust gets spent. When the page responds instantly, people finish.

One caveat on metrics. Time-to-interactive was the standard metric back then. Lighthouse dropped TTI in version 10 (2023), and Google replaced First Input Delay with Interaction to Next Paint (INP) as a Core Web Vital in March 2024. If you’re measuring this today, track INP and LCP on the product and checkout routes, segmented by device. Desktop averages will hide the problem.

What I’d do first on your marketplace

  1. Measure INP and LCP on product, cart and checkout pages, on real mobile traffic.
  2. Server-render product and category routes if they’re client-rendered today.
  3. Count the screens from cart to paid. Remove one.
  4. Move order confirmation to webhooks and add idempotency keys.
  5. Lazy-load anything a shopper doesn’t need before paying.

FAQ

Does SSR alone reduce cart abandonment?

No. SSR improves first paint and crawlability. Abandonment dropped on Cercle because SSR, a shorter Stripe path and a lighter bundle all landed together. SSR without a faster checkout mostly helps SEO.

Should I use Stripe Checkout or build a custom form?

Start with Stripe Checkout or the Payment Element. You get wallets, Link autofill and 3D Secure handling without building them. Build custom only when you have a measured reason.

Is Next.js a good choice for a marketplace?

Yes, when you need crawlable product pages and fast first paint. Pair it with a backend that owns orders and payments. On Cercle that was Rails 6.


Full project details are in the Cercle case study. If your marketplace has the same problem, see hire a Next.js developer.