mosaic
  • Overview
  • Integration
    • Next.js
    • Create React App
    • Webpack
  • Getting started
    • Extensions
    • Themes
  • Tutorials
    • Mosaic + React
    • Mosaic + Webpack
  • Install an extension
    • Install a local extension
    • Install with a package manager
    • Enable or disable an extension
  • Develop an extension
    • Anatomy of an extension
    • Namespaces
    • Runtime plugins
    • Build configuration plugins
  • CRA features
    • CRACO plugins
  • Next.js features
    • Styles
    • Pages
    • Common props
  • Architecture examples
    • Router
  • Themes
    • Parent theme system
    • File shadowing
  • Experimental
    • Module preferences
    • File provisioning
  • in-depth
    • How does it work?
Powered by GitBook
On this page
  • Source implementation
  • Filling such a router by using plugins

Was this helpful?

  1. Architecture examples

Router

Reviewing a React router component implemented with Mosaic for Mosaic

PreviousCommon propsNextParent theme system

Last updated 4 years ago

Was this helpful?

In any frontend or backend application, the router is a place which is one of the most important ones to make plugin-friendly, when using Mosaic. Any amount of routes can be added to it, if it is designed correctly.

This article will demonstrate a router design from project, which is written completely in Mosaic.

Source implementation

Let's see the router itself! It is also available on . This is exactly the form of the router at the moment of writing this article.

It is clearly visible that the router does not actually render any routes! It just provides several convenient points for modification with Mosaic : _beforeSwitchRenderList, _switchRenderList and _afterSwitchRenderList

import { createSortedRenderMap } from '@scandipwa/framework/src/util/SortedMap';
import { createBrowserHistory } from 'history';
import { PureComponent } from 'react';
import { Router as ReactRouter } from 'react-router';
import { Switch } from 'react-router-dom';

export const history = createBrowserHistory({ basename: '/' });

/** @namespace Router/Component/Router/Component/RouterComponent */
export class RouterComponent extends PureComponent {
    static propTypes = {};

    _beforeSwitchRenderList = createSortedRenderMap({});

    _switchRenderList = createSortedRenderMap({});

    _afterSwitchRenderList = createSortedRenderMap({});

    contentRenderList = createSortedRenderMap({
        routerBeforeSwitch: this._beforeSwitchRenderList.render,
        routerRenderSwitch: this.renderSwitch.bind(this),
        routerAfterSwitch: this._afterSwitchRenderList.render
    });

    renderSwitch() {
        return (
            <Switch>
                { this._switchRenderList.render() }
            </Switch>
        );
    }

    renderRouterContent() {
        return this.contentRenderList.render();
    }

    render() {
        return (
            <ReactRouter history={ history }>
                { this.renderRouterContent() }
            </ReactRouter>
        );
    }
}

export default RouterComponent;

Filling such a router by using plugins

/* eslint-disable @scandipwa/scandipwa-guidelines/jsx-no-props-destruction */
import { createElement, lazy, Suspense } from 'react';
import { Route } from 'react-router';

import CartFallbackPage from '../component/CartFallbackPage';

const CartPage = lazy(() => import('../component/CartPage'));

const addCartPage = (member) => {
    const CART_PAGE_POSITION = 1000;

    member.addItem(
        () => createElement(Route, {
            path: '/cart',
            exact: true,
            render: (props) => (
                <Suspense fallback={ <CartFallbackPage /> }>
                    <CartPage { ...props } />
                </Suspense>
            )
        }),
        'routerCartPage',
        CART_PAGE_POSITION
    );

    return member;
};

export default {
    'Router/Component/Router/Component/RouterComponent': {
        'member-property': {
            _switchRenderList: addCartPage
        }
    }
};

A router is pointless without routes, right? So let's add a route to the one defined above! We will use the for this purpose.

As you see, the plugin declaration file presented below modifies the of the class above, a member called _switchRenderList of member-property

It implements a addCartPage, which accepts the initial member - sorted render map _switchRenderList declared above, adds an additional item to that map and returns the modified value to the application.

@scandipwa/shopify
this link
runtime plugins
Mosaic runtime plugins
namespace
target kind
plugin (proxy) function