# Sitemap and routing

The navigational structure and routing are deeply connected through a common sitemap.json file. This file defines all possible routes to which the user can navigate. Coupled with the current user identity and authorization checks, we only define the routes that are accessible. Meaning; the user can never navigate to an url that he/she does not have access to.

The sitemap is located in `frontend-workstation`.
Each route has the following definition:

```typescript
interface Permission {
    permission: string;
    privilege?: string;
}

interface SitemapNode {
    key: string;

    url?: string | string[];
    match?: string | string[];
    module?: string;

    featureFlag?: string | string[];
    featureControl?: string | string[];
    permissions: string | string[] | Permission[];
    subaccountRestriction: bool;

    variants?: SitemapNode[];
    items?: SitemapNode[];
}
```

## The `module` property

```json
{
    "items": [
        {
            "module": "frontend-audience-page",
            "url": "/audience"
        }
    ]
}
```

The `module` property defines a remote module hosted on the CDN.
e.g. https://cdn.theorchard.io/frontend-audience-page/dml.json. Matching the route will load the module into the current placeholder location.

If no `module` is defined, the default behavior for menu component is to use normal anchor tags and hrefs.

## The `match` and `url` properties

```json
{
    "items": [
        {
            "module": "my-module",
            "url": "/some/place",
            "match": "/some*"
        }
    ]
}
```

The `match` property allows for regex expression matching against current location. In the example above, the menu component would render a menu item with the given `url`, but navigating to `"/some"` or `"/some/nowhere"`, would load the given module for all matching paths.

If not using the `match` property, the `url` property is used to match the route.

**NOTE** the menu component in `frontend-workstation` will only render routes as menu items with valid `url` properties.

## Authorization checks

By using the `featureFlag`, `featureControl` and `permissions` properties, we can perform various authorization checks on the route and user. If any of the checks fail, the route is not included and is not reachable. There is an optional property named `subaccountRestriction` which can be used in order to restrict subaccounts accessing the route.

## Variants

It is possible to define different variations of each route using the `variants` property. By running authorization checks for each variant, the first allowed is merged with the base route. You may think of it as `if elseif` clauses.

```json
{
    "items": [
        {
            "module": "my-old-module",
            "url": "/page",
            "match": "/some*",
            "variants": [
                {
                    "featureControl": "admins",
                    "featureFlag": "somecool_feature",
                    "module": "my-new-cool-admin-module",
                    "url": "/admin/page"
                },
                {
                    "featureFlag": "somecool_feature",
                    "module": "my-new-cool-module"
                }
            ]
        }
    ]
}
```

If the user passes the auth checks for the first variant, the module to load would be `my-new-cool-admin-module` and the url `/admin/page`. If user has the feature flag, but is not admin, then the module would be `my-new-cool-module`. Else it fallbacks to `my-old-module`.

## Items

Each route may define child routes using the `items` property. Authorization checks are inherited so no children are accessible if parent is not.

```json
{
    "items": [
        {
            "url": "/section",
            "match": "/section*",
            "items": [
                {
                    "url": "/section/page1",
                    "module": "frontend-page"
                },
                {
                    "url": "/section/page2",
                    "module": "frontend-page"
                }
            ]
        }
    ]
}
```

**NOTE** the menu component in `frontend-workstation` will render parent routes as sections with a subnav component. Where each child is a menu item in the subnav.
