React Storefront

React Storefront Features

React Storefront makes it easy to build a beautiful, fast, and reliable ecommerce PWA by providing the following features:

Universal Router

React Storefront's router allows you declare both client and server routes and control caching behavior from a single location. For example, here's a route for a product page that works on both the client and the server:

new Router().get(
    edge: { maxAgeSeconds: 300 }, // cache the result at the edge for 5 minutes
    client: true // and on the client using a service worker
  fromClient({ page: 'Product' }), // display the product view
  fromServer('./product/product-handler') // call the product API endpoint


React Storefront makes it easy to prefetch and cache links as the user scrolls them into view. Stay one step ahead of your users and make page transitions lightning fast!

<Link prefetch="visible" to="/products/1">
  Product 1

SSR by Default

React Storefront automatically renders the initial landing page on the server by default. This means faster load times for users and better SEO. No configuration is necessary.

Code Splitting

React Storefront automatically minimizes bundle size by splitting pages into separate bundles. This ensures that time-to-responsive is as fast as possible.

import universal from 'react-universal-component'
import Views from 'react-storefront/Views'

// ...
  loading={() => <LoadMask />}
    Home: universal(() => import('./Home')),
    Category: universal(() => import('./Category')),
    Product: universal(() => import('./Product'))

React Components

React Storefront provides several components for common e-commerce features built on top of Material UI.

import ImageSwitcher from 'react-storefront/ImageSwitcher'

// ...
;<ImageSwitcher images={product.images} thumbnails={product.thumbnails} showIndicators />


Control the look and feel of application components by creating a custom theme and/or overriding component default styles using JSS.

import createTheme from 'react-storefront/createTheme'
import { darken, lighten } from '@material-ui/core/styles/colorManipulator'

const brandColor = '#0C79AD'

export default createTheme({
  palette: {
    primary: {
      light: lighten(brandColor, 0.12),
      main: brandColor,
      dark: darken(brandColor, 0.12),
      contrastText: '#fff'

State Management

React Storefront uses mobx-state-tree to provide structured state management based on observables.

import { types } from 'mobx-state-tree'
import ProductModelBase from 'react-storefront/model/ProductModelBase'

const ProductModel = types.compose(
  types.model('ProductModel', {
    sku: types.string

Automatic Service Worker Generation

React Storefront uses Google's workbox to automatically generate a service worker that supports static and runtime caching. There's no need to create a separate service worker configuration since all caching in conveniently expressed in your router definition.

Advanced Client and Edge Caching

React Storefront provides a simple directive to control how responses are cached in the browser and at the edge for ultra-fast response times. You can also cache multiple variants of the same URL when running on the Moovweb XDN using createCustomCacheKey()

import {
} from 'react-storefront/router'

new Router().get(
    client: true, // cache in the browser using the service worker
    edge: {
      maxAgeSeconds: 300, // cache the result at the edge for 5 minutes
      key: createCustomCacheKey().addCookie('currency') // cache a separate response for each value of the currency cookie
  // ...


React Storefront makes it easy to integrate with tag managers and individual third-party analytics solutions.

import React, { Component } from 'react'
import AnalyticsProvider from 'react-storefront/AnalyticsProvider'
import TrackPageViews from 'react-storefront-extensions/TrackPageViews'
import GoogleTagManagerAnalyticsTarget from 'react-storefront-extensions/GoogleTagManagerCommerceTarget

const gtm = new GoogleTagManagerCommerceTarget()
  .configureExperiments({ cookieName: 'moov_experience' })

export default class App extends Component {
  render() {
    return (
      <AnalyticsProvider targets={[gtm]}>
          {/* ... */}