# Merchant Center Proxy Router Learn about the Merchant Center Proxy Router and how it works with Custom Applications. This page applies only to Custom Applications. When you use the Merchant Center, you can switch between the built-in applications and the externally developed applications available to your Project. The URL of the Merchant Center always uses the same origin and only differs in the URI, depending on the Project and application. For example: ``` https://mc..commercetools.com/:projectKey/dashboard https://mc..commercetools.com/:projectKey/products https://mc..commercetools.com/:projectKey/orders https://mc..commercetools.com/:projectKey/custom-channels ``` This way, it looks like you're using a single web application, even though there are multiple applications underneath. ## Server-side routing When a user accesses the Merchant Center through the browser, the request to render the page goes through a server component called Merchant Center Proxy Router. This server is primarily responsible for matching the incoming request to the appropriate Custom Application using the `entryPointUriPath` ([the identifier of the Custom Application](/merchant-center-customizations/tooling-and-configuration/custom-application-config.md#entrypointuripath)). The request is then [forwarded](/merchant-center-customizations/concepts/merchant-center-proxy-router.md#forward-requests) to the actual [URL location of the Custom Application](/merchant-center-customizations/tooling-and-configuration/custom-application-config.md#envproductionurl), which responds with the `index.html` file. A Custom Application is a single-page application that uses client-side routing. This means you must configure your hosting provider to rewrite all requests to serve the `index.html` file. Conceptually it would look something like this: `/* --> /index.html`. To learn more, see [Forward requests](/merchant-center-customizations/concepts/merchant-center-proxy-router.md#forward-requests). ```mermaid flowchart TD subgraph User Merchant -->|"https://mc.{cloud_region}.commercetools.com" | Browser(Browser) end subgraph Router direction RL Matcher{Path matcher} --> Config[(Config)] end subgraph hostingInternal [Hosting internal] App1["Custom Application\nCSS / JS / HTML"] end subgraph hostingExternal [Hosting external] App2["Custom Application\nCSS / JS / HTML"] end User -->|"HTTP\n/:projectKey/:entryPointUryPath"| Router Router -->|products| hostingInternal Router -->|custom-channels| hostingExternal ``` The request goes through the following steps: 1. The user accesses the Merchant Center at the following path `/my-project/my-app`. 2. The request goes through the Merchant Center Proxy Router, which successfully matches the `my-app` identifier to the `my-project` Project. 3. The configuration for the Custom Application `my-app` is loaded. 4. The request is [forwarded](/merchant-center-customizations/concepts/merchant-center-proxy-router.md#forward-requests) to the URL of the server hosting the Custom Application. 5. The server hosting the Custom Application responds with the `index.html` file. 6. The Custom Application `my-app` is rendered in the browser. ### Forward requests When the Merchant Center Proxy Router matches a request to a Custom Application, it forwards the original request URI to the Custom Application's configured URL. ``` # FROM https://mc..commercetools.com/:projectKey/:entryPointUriPath/* # TO https:///:projectKey/:entryPointUriPath/* ``` The `` is the Custom Application [production URL](/merchant-center-customizations/tooling-and-configuration/custom-application-config.md#envproductionurl). Therefore, the hosting server of the Custom Application must configure URL rewrite rules to handle all requests and serve the `index.html` file. For example, given the following data: - Application production URL: `https://custom-channels.netlify.app` - Application `entryPointUriPath`: `custom-channels` When the user accesses the application in the Merchant Center at `https://mc..commercetools.com/:projectKey/custom-channels`, the Merchant Center Proxy Router forwards the request to the following URL `https://custom-channels.netlify.app/:projectKey/custom-channels`. Similarly, any of the following example URLs returns the `index.html` file: ``` https://custom-channels.netlify.app https://custom-channels.netlify.app/:projectKey/custom-channels https://custom-channels.netlify.app/:projectKey/custom-channels/new https://custom-channels.netlify.app/:projectKey/custom-channels/123/teams ``` Configuring rewrite rules is specific to each hosting provider. For more information on how to configure rewrite rules, see the list of hosting services on our [Deployment overview](/merchant-center-customizations/deployment/overview.md) page. ## Client-side routing After the browser finishes rendering the `index.html` file, the Custom Application uses client-side routing to handle the URI location path. Each Custom Application has a built-in router and a default route configured to match the path `/:projectKey/:entryPointUriPath`. The value of the `entryPointUriPath` is defined in the [Custom Application config file](/merchant-center-customizations/tooling-and-configuration/custom-application-config.md) and exposed via the `window.app` [runtime environment](/merchant-center-customizations/tooling-and-configuration/custom-application-config.md#runtime-application-environment). Hence, the runtime value of the `entryPointUriPath` must match the value defined in the [Custom Application configuration in the Merchant Center](/merchant-center/managing-custom-applications.md). For example, if the `entryPointUriPath` is `custom-channels` and the user accesses the URL `/my-project/custom-channels`, the Custom Application renders correctly because the route matches. ```js //mc..commercetools.com/:projectKey/custom-channels // custom-channels https: window.app.entryPointUriPath; // custom-channels ``` ### Page reloading behavior Each Custom Application defines its routes. However, there might be links to other applications that the Custom Application routes won't match. The same applies when a user clicks on an item in the Merchant Center main menu. When no route matches the new URI path, the Custom Application forces a full page reload. At this point, the request goes through the Merchant Center Proxy Router, letting the [server-side router](/merchant-center-customizations/concepts/merchant-center-proxy-router.md#server-side-routing) handle the matching of the route. In most cases, this results in rendering a different Custom Application. ```mermaid sequenceDiagram autonumber Browser->>+Merchant Center Proxy Router: URI path (/:projectKey/:entryPointUriPath/*) Merchant Center Proxy Router->Merchant Center Proxy Router: Matching Application URL Merchant Center Proxy Router->>Hosting provider: Application URL + URI Path Hosting provider->Hosting provider: Single-page application router Hosting provider->>Merchant Center Proxy Router: index.html is returned Merchant Center Proxy Router->>Browser: Render app Browser->Browser: Matching route (client-side) note right of Browser: The entryPointUriPath configured in the app alt Is route path matching Browser->Browser: OK (render) else Browser->>Merchant Center Proxy Router: NO (page reload) end ``` Use the same `entryPointUriPath` value in the Custom Application config file and the Merchant Center configuration. If there's a mismatch, the client-side routing will force a page reload to let the Merchant Center Proxy Router handle the route match, which renders the same application again, causing infinite reloads. You can detect the reloading issue by inspecting the value of `window.app.entryPointUriPath` in the browser's developer tools and compare it with the value in the URI path. ```js //mc..commercetools.com/:projectKey/custom-channels // custom-channels https: window.app.entryPointUriPath; // custom-channels-2 ``` ## Security Headers The Merchant Center Proxy Router enforces the following HTTP security headers when serving the response from the Custom Application location. Some headers are added automatically, while others can be configured for additional customization. ### Referrer-Policy The [Referrer-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) header is added by default to control how much referrer information is included with requests. ``` Referrer-Policy: same-origin ``` ### Strict-Transport-Security The [Strict-Transport-Security](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) header ensures that the application is accessed over HTTPS and that any attempts to access it using HTTP are automatically converted to HTTPS. By default, the header is set to a maximum age of 1 year and includes subdomains and preloading. ``` Strict-Transport-Security: max-age=31536000; includeSubDomains; preload ``` ### X-Content-Type-Options The [X-Content-Type-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) HTTP response header is added by default to ensure that the [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) specified in the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) headers are strictly followed and not altered. This header prevents [MIME type sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) by confirming that the MIME types are intentionally set. ``` X-Content-Type-Options: nosniff ``` ### X-Frame-Options The [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) header is added by default to prevent the page from being rendered in a `,