---
title: "Angular middleware"
slug: "angular-middleware"
abstract: "Learn about the built-in Express.js middleware available in Content SDK Angular apps and their configuration options."
---
# Angular middleware

The `src/server.ts` file in a Content SDK Angular application contains customizable server-side pre-processing logic for incoming requests. This logic runs through Express.js middleware. This topic describes the built-in middleware and their roles.

## Middleware overview

The following table summarizes each middleware, when it runs, and its purpose. For detailed configuration options, see [Middleware reference](https://doc.sitecore.com/sai/en/developers/content-sdk/angular/1x/angular-middleware.html#middleware-reference).

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Middleware</p></th><th class="th"><p>Server navigation</p></th><th class="th"><p>Browser navigation</p></th><th class="th"><p>Editing/preview modes</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p>Loader data service</p></td><td class="td"></td><td class="td"><p>✓</p></td><td class="td"></td><td class="td"><p>Provides layout, dictionary, and other loader data during browser navigation.</p></td></tr><tr><td class="td"><p>Personalize</p></td><td class="td"><p>✓</p></td><td class="td"><p>✓</p></td><td class="td"></td><td class="td"><p>Resolves personalization data for the current route.</p></td></tr><tr><td class="td"><p>Multisite</p></td><td class="td"><p>✓</p></td><td class="td"><p>✓</p></td><td class="td"></td><td class="td"><p>Resolves the target site by hostname in multi-site configurations.</p></td></tr><tr><td class="td"><p>Bot detection</p></td><td class="td"><p>✓</p></td><td class="td"><p>✓</p></td><td class="td"></td><td class="td"><p>Detects bot requests and reports bot page views, skipping personalization for bot traffic.</p></td></tr><tr><td class="td"><p>Redirects</p></td><td class="td"><p>✓</p></td><td class="td"><p>✓</p></td><td class="td"></td><td class="td"><p>Matches requests against SXA redirect items and redirects when there's a match.</p></td></tr><tr><td class="td"><p>Editing config</p></td><td class="td"></td><td class="td"></td><td class="td"></td><td class="td"><p>Handles <code class="code">/api/editing/config</code> requests used internally by Pages Editor.</p></td></tr><tr><td class="td"><p>Editing render</p></td><td class="td"></td><td class="td"></td><td class="td"><p>✓</p></td><td class="td"><p>Handles <code class="code">/api/editing/render</code> requests that enable editing in Pages Editor.</p></td></tr><tr><td class="td"><p>Cache revalidate</p></td><td class="td"></td><td class="td"></td><td class="td"></td><td class="td"><p>Processes <code class="code">/api/revalidate</code> requests to revalidate loader cache entries.</p></td></tr><tr><td class="td"><p>Sitemap</p></td><td class="td"></td><td class="td"></td><td class="td"></td><td class="td"><p>Generates and serves XML sitemaps.</p></td></tr><tr><td class="td"><p>Robots</p></td><td class="td"></td><td class="td"></td><td class="td"></td><td class="td"><p>Generates and serves the <code class="code">robots.txt</code> file.</p></td></tr></tbody></table>

## Middleware reference

The following sections explain the middleware available in the Content SDK for Angular.

### Loader data service middleware

This middleware is required for the Angular application to function correctly. Do not remove it. The Loader data service middleware supplies layout, dictionary, and other loader data to [Content SDK loaders](https://doc.sitecore.com/sai/en/developers/content-sdk/angular/1x/loaders.html) during browser navigation.

Register this middleware in `server.ts` using the `createLoaderDataServiceMiddleware()` factory function.

#### Options reference

```ts
interface LoaderDataServiceOptions {
  loaders: LoaderRegistry;
  cache: LoaderCache;
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">loaders</code></p></td><td class="td"><p><code class="code">LoaderRegistry</code></p></td><td class="td"><p>The loader registry, equivalent to <code class="code">provideLoaderRegistry(LOADERS)</code>.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">cache</code></p></td><td class="td"><p><code class="code">LoaderCache</code></p></td><td class="td"><p>The loader cache instance initialized earlier in <code class="code">server.ts</code>.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr></tbody></table>

### Personalize middleware

The Personalize middleware resolves personalization data for the current route. The resulting `variantId` is used when resolving layout data from the SitecoreAI Edge endpoint.

Register this middleware in `server.ts` using the `createPersonalizeMiddleware()` factory function.

#### Options reference

```ts
type PersonalizeMiddlewareOptions = {
  enabled?: boolean;
  skip?: (req: ExpressRequest) => boolean;
  // configure paths to run middleware for
  matcher?: {
    includePaths?: (string | RegExp)[];
    excludePaths?: (string | RegExp)[];
  };
  // Mirrors the SitecoreConfig['personalize'] section
  personalize: {
    enabled?: boolean;
    edgeTimeout?: number;
    cdpTimeout?: number;
    scope?: string;
    channel?: string;
    currency?: string;
  };
  // Mirrors the SitecoreConfig['api']['edge'] section
  api: {
    edge: {
      contextId?: string;
      clientContextId?: string;
      edgeUrl?: string;
    }
  };
  locales?: string[];              // list of locales for personalize to use
  defaultLanguage?: string;        // default: 'en'
  defaultSite?: string;
  personalizeService?: PersonalizeService;
  getExtraUtmParams?: (req: ExpressRequest) => Partial<{
    campaign?: string;
    source?: string;
    medium?: string;
    content?: string;
    [key: string]: string | undefined;
  }>;
};
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">enabled</code></p></td><td class="td"><p><code class="code">boolean</code></p></td><td class="td"><p>Enables or disables the middleware.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">skip</code></p></td><td class="td"><p><code class="code">(req: ExpressRequest) => boolean</code></p></td><td class="td"><p>A callback that skips middleware execution for specific requests.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">matcher</code></p></td><td class="td"><p><code class="code">object</code></p></td><td class="td"><p>Configures path inclusion and exclusion rules for the middleware.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">personalize</code></p></td><td class="td"><p><code class="code">object</code></p></td><td class="td"><p>Personalization settings. Maps to the <code class="code">personalize</code> section of your Sitecore configuration.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">api</code></p></td><td class="td"><p><code class="code">object</code></p></td><td class="td"><p>API endpoint settings. Maps to the <code class="code">api.edge</code> section of your Sitecore configuration.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">locales</code></p></td><td class="td"><p><code class="code">string[]</code></p></td><td class="td"><p>List of locales for personalization.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultLanguage</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback language.</p><p>Default: <code class="code">'en'</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultSite</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback site name.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">personalizeService</code></p></td><td class="td"><p><code class="code">PersonalizeService</code></p></td><td class="td"><p>A custom personalize service instance.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">getExtraUtmParams</code></p></td><td class="td"><p><code class="code">function</code></p></td><td class="td"><p>Returns additional UTM parameters to include in personalization requests.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

### Multisite middleware

The Multisite middleware resolves the target site for an incoming request based on hostname. Use this middleware when you have multiple sites configured in Sitecore.

Register this middleware in `server.ts` using the `createMultisiteMiddleware()` factory function.

#### Options reference

```ts
type MultisiteMiddlewareOptions = BaseMiddlewareOptions & {
  // From AngularSitecoreConfig['multisite']
  enabled?: boolean;
  // configure if site should be resolved from sc_site cookie. default false
  useCookieResolution?: (
    req?: ExpressRequest,
    res?: ExpressResponse
  ) => boolean;
  // sites to consider for resolution
  sites?: SiteInfo[];
  defaultSite?: string;            // fallback when resolution fails
};
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">enabled</code></p></td><td class="td"><p><code class="code">boolean</code></p></td><td class="td"><p>Enables or disables the middleware.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">useCookieResolution</code></p></td><td class="td"><p><code class="code">function</code></p></td><td class="td"><p>When it returns <code class="code">true</code>, the site is resolved from the <code class="code">sc_site</code> cookie. Defaults to <code class="code">false</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">sites</code></p></td><td class="td"><p><code class="code">SiteInfo[]</code></p></td><td class="td"><p>The list of sites to consider during resolution.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultSite</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback site name when resolution fails.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

### Editing config middleware

The Editing config middleware processes `/api/editing/config` requests used internally by Pages Editor. We recommend that you do not customize this middleware.

Register this middleware in `server.ts` using the `createEditingConfigMiddleware()` factory function.

#### Options reference

```ts
interface CreateEditingConfigMiddlewareOptions {
  components: ComponentMap;        // required — same as SITECORE_COMPONENT_MAP
  metadata?: Metadata;             // inline; if set, metadataImport is ignored
  metadataImport?: MetadataImportFn; // dynamic function for metadata resolution
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">components</code></p></td><td class="td"><p><code class="code">ComponentMap</code></p></td><td class="td"><p>The component map, equivalent to <code class="code">SITECORE_COMPONENT_MAP</code>.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">metadata</code></p></td><td class="td"><p><code class="code">Metadata</code></p></td><td class="td"><p>Inline metadata. If set, <code class="code">metadataImport</code> is ignored.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">metadataImport</code></p></td><td class="td"><p><code class="code">MetadataImportFn</code></p></td><td class="td"><p>A dynamic function for metadata resolution.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

### Editing render middleware

The Editing render middleware processes `/api/editing/render` requests that enable editing in Pages Editor.

Register this middleware in `server.ts` using the `createEditingRenderMiddleware()` factory function.

#### Options reference

```ts
interface CreateEditingRenderMiddlewareOptions {
  // Allows apps to remap the editor's `route` query parameter to their own URL
  resolvePageUrl?: (
    itemPath: string,
    previewData: EditingPreviewData
  ) => string;
  // Extra query parameters propagated into the editing preview data
  // (e.g. deployment-protection bypass tokens).
  allowedQueryParams?: AllowedQueryParams;
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">resolvePageUrl</code></p></td><td class="td"><p><code class="code">function</code></p></td><td class="td"><p>Remaps the editor's route query parameter to a custom URL.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">allowedQueryParams</code></p></td><td class="td"><p><code class="code">AllowedQueryParams</code></p></td><td class="td"><p>Extra query parameters propagated into the editing preview data, such as deployment-protection bypass tokens.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

### Cache revalidate middleware

The Cache revalidate middleware processes the `/api/revalidate` endpoint. You can use this endpoint in combination with webhooks to revalidate loader cache entries. For more information, see [Loaders cache layer and tags revalidation](https://doc.sitecore.com/sai/en/developers/content-sdk/angular/1x/loaders-cache-layer-and-tags-revalidation.html "Loaders cache layer and tags revalidation").

Register this middleware in `server.ts` using the `createSitecoreRevalidateMiddleware()` factory function.

#### Options reference

```ts
interface SitecoreRevalidateMiddlewareOptions {
  cache: LoaderCache;              // loader cache instance initialized earlier in the file
  secret?: string;                 // default: process.env.SITECORE_REVALIDATE_SECRET
  defaultLocale?: string;          // default: 'en'
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">cache</code></p></td><td class="td"><p><code class="code">LoaderCache</code></p></td><td class="td"><p>The loader cache instance initialized earlier in <code class="code">server.ts</code>.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">secret</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>The revalidation secret. Defaults to <code class="code">process.env.SITECORE_REVALIDATE_SECRET</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultLocale</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback locale. Defaults to <code class="code">'en'</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

### Sitemap middleware

The Sitemap middleware generates and serves XML sitemaps at `/sitemap.xml` and numbered `/sitemap-{id}.xml` paths.

Register this middleware in `server.ts` using the `createSitemapMiddleware()` factory function.

#### Options reference

```ts
interface CreateSitemapMiddlewareOptions {
  client: SitecoreClient;
  sites: SiteInfo[];
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">client</code></p></td><td class="td"><p><code class="code">SitecoreClient</code></p></td><td class="td"><p>The Sitecore client instance.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">sites</code></p></td><td class="td"><p><code class="code">SiteInfo[]</code></p></td><td class="td"><p>The list of sites to include in the sitemap.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr></tbody></table>

### Robots middleware

The Robots middleware generates and serves the `robots.txt` file at the `/robots.txt` path.

Register this middleware in `server.ts` using the `createRobotsMiddleware()` factory function.

#### Options reference

```ts
interface CreateRobotsMiddlewareOptions {
  client: SitecoreClient;
  sites: SiteInfo[];
}
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">client</code></p></td><td class="td"><p><code class="code">SitecoreClient</code></p></td><td class="td"><p>The Sitecore client instance.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr><tr><td class="td"><p><code class="code">sites</code></p></td><td class="td"><p><code class="code">SiteInfo[]</code></p></td><td class="td"><p>The list of sites to use for <code class="code">robots.txt</code> generation.</p><p><span class="emphasis"><em>Required</em></span></p></td></tr></tbody></table>

### Bot detection middleware

This middleware runs bot detection once per request. It detects bots based on the User-Agent, marks the request/response with the `sc_bot` cookie, and dispatches a dedicated bot page-view event for the resolved site/language. For more information, see [Lightweight tracking](https://doc.sitecore.com/sai/en/developers/content-sdk/angular/1x/lightweight-tracking.html "Lightweight tracking").

Register this middleware in `server.ts` using the `createBotTrackingMiddleware()` factory function.

#### Options reference

```ts
type BotTrackingMiddlewareOptions = Omit<BaseMiddlewareOptions, 'enabled'> & {
  // Mirrors the AngularSitecoreConfig['api']['edge'] section
  api: {
    edge: {
      contextId?: string;
      clientContextId?: string;
      edgeUrl?: string;
    }
  };
  // locales used to extract the language from the request path
  locales?: string[];
  // fallback language when the path has no locale prefix. Default 'en'
  defaultLanguage?: string;
  // fallback site when not resolved by multisite or the site cookie
  defaultSite?: string;
};
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">contextId</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Edge context ID. Required to send bot page-view events.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">clientContextId</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Edge client context ID.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">edgeUrl</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>URL of the SitecoreAI Edge endpoint that bot page-view events are sent to.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">locales</code></p></td><td class="td"><p><code class="code">string[]</code></p></td><td class="td"><p>Locales used to extract the language from the request path.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultLanguage</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback language when the request path has no locale prefix.</p><p>Default: <code class="code">'en'</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultSite</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback site name when not resolved by the multisite middleware or the site cookie.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>

> [!note]
> This middleware does not accept an `enabled` option. It is skipped automatically for editing/preview requests, non-matching paths, prefetch requests, and on `localhost` or in a `development` environment, unless the `SITECORE_ENABLE_BOT_TRACKING` environment variable is set to `true`.

### Redirects middleware

The Redirects middleware matches the current request against SXA redirect items and redirects the request when there's a matching item.

Register this middleware in `server.ts` using the `createRedirectsMiddleware()` factory function.

> [!note]
> This logic runs on both server and browser navigation. However, due to Angular routing API limitations, 301/302 redirects produce browser navigation only.

#### Options reference

```ts
type RedirectsMiddlewareOptions = BaseMiddlewareOptions & {
  // Mirrors the SitecoreConfig['redirects'] section
  enabled?: boolean;
  // Mirrors the SitecoreConfig['api']['edge'] section
  contextId?: string;
  clientContextId?: string;
  edgeUrl?: string;
  // Mirrors the SitecoreConfig['api']['local'] section
  apiHost?: string;
  apiKey?: string;
  path?: string;
  // Locales configured for the app (derived from angular.locales)
  locales?: string[];
  defaultLanguage?: string;
  defaultSite?: string;
  // Sites used to resolve the site's default language for the $siteLang token
  sites?: SiteInfo[];
  // Override the redirects service instance (e.g. for testing)
  redirectsService?: RedirectsService;
};
```

<table style="width:100%;" class="informaltable frame-void rules-rows"><thead><tr><th class="th"><p>Property</p></th><th class="th"><p>Type</p></th><th class="th"><p>Description</p></th></tr></thead><tbody><tr><td class="td"><p><code class="code">enabled</code></p></td><td class="td"><p><code class="code">boolean</code></p></td><td class="td"><p>Enables or disables the middleware.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">contextId</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Edge context ID used to fetch redirects, unless local API configuration is provided instead.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">clientContextId</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Edge client context ID.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">edgeUrl</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>URL of the SitecoreAI Edge endpoint that redirects are fetched from.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">apiHost</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Local API hostname used to fetch redirects from a local instance instead of Edge.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">apiKey</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Local API key, used together with <code class="code">apiHost</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">path</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>GraphQL endpoint path appended to <code class="code">apiHost</code> to form the full endpoint URL.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">locales</code></p></td><td class="td"><p><code class="code">string[]</code></p></td><td class="td"><p>Locales configured for the app, used to match locale-versioned redirect rules. Derived from <code class="code">angular.locales</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultLanguage</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback language when the request path has no locale prefix.</p><p>Default: <code class="code">'en'</code>.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">defaultSite</code></p></td><td class="td"><p><code class="code">string</code></p></td><td class="td"><p>Fallback site name when not resolved by the multisite middleware or the site cookie.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">sites</code></p></td><td class="td"><p><code class="code">SiteInfo[]</code></p></td><td class="td"><p>Sites used to resolve the target site's default language for the <code class="code">$siteLang</code> redirect token.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr><tr><td class="td"><p><code class="code">redirectsService</code></p></td><td class="td"><p><code class="code">RedirectsService</code></p></td><td class="td"><p>Override the redirects service instance, for example for testing.</p><p><span class="emphasis"><em>Optional</em></span></p></td></tr></tbody></table>
