# Router

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.&#x20;

This article will demonstrate a router design from [@scandipwa/shopify](https://github.com/scandipwa/shopify) project, which is written completely in Mosaic.

## Source implementation

Let's see the router itself! It is also available on [this link](https://github.com/scandipwa/shopify/blob/master/packages/router/src/component/Router/Router.component.js). This is exactly the form of the router at the moment of writing this article.&#x20;

It is clearly visible that the router does not actually render any routes! It just provides several convenient points for modification with Mosaic [runtime plugins](https://docs.mosaic.js.org/develop-an-extension/plugins): `_beforeSwitchRenderList`, `_switchRenderList` and `_afterSwitchRenderList`

```javascript
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

A router is pointless without routes, right? So let's add a route to the one defined above! We will use the [Mosaic runtime plugins](https://docs.mosaic.js.org/develop-an-extension/plugins) for this purpose.

As you see, the plugin declaration file presented below modifies the [namespace](https://docs.mosaic.js.org/develop-an-extension/plugins#target-namespace) of the class above, a member called `_switchRenderList` of [target kind](https://docs.mosaic.js.org/develop-an-extension/plugins#target-kind) `member-property` &#x20;

It implements a [plugin (proxy) function](https://docs.mosaic.js.org/develop-an-extension/plugins#implement-proxy-function) `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.

```javascript
/* 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
        }
    }
};

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mosaic.js.org/architectural-solutions/router.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
