# Self-Hosting Transcend Consent (/docs/consent-management/reference/self-hosting)

## Overview [#overview]

Transcend Consent's multiple JavaScript modules and synchronization endpoint can be self-hosted on your own infrastructure to help comply with internal security requirements.

## JavaScript Modules [#javascript-modules]

We recommend using a reverse proxy with a simple caching setup to host your consent manager on your own infrastructure. This will ensure that you can continue to update your consent manager through the Transcend dashboard.

See [this nginx config](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) for an example of setting up a reverse proxy in nginx.

After you have set up your self-hosted modules, you can use the following HTML snippet to load consent manager modules using your own infrastructure:

```html
<script
  src="/path/to/airgap.js"
  data-ui="/path/to/ui.js"
  data-xdi="/path/to/xdi.js"
  data-sync-endpoint-map='{"example.com": "https://sync.example.com", "example.net": "https://sync.example.net/"}'
></script>
```

## Sync Endpoint [#sync-endpoint]

Hosting your own first-party XDI sync endpoint is an easy two-step process:

1\. Host a publicly-accessible static page with this HTML on all of your [sites](https://web.dev/same-site-same-origin/), replacing the value of `data-sync-groups` with a space-separated list of sites that you wish to sync between.

```html
<!doctype html>
<script
  src="https://transcend-cdn.com/cm/{your-bundle-id}/xdi.js"
  data-xdi-commands="ConsentManager:Sync"
  data-sync-groups='{"site1":["your-site.example"], "site2":["your-other-site.example"]}'
></script>
```

2\. Update your consent manager script tag as such. Take note to enter the URL(s) to the page(s) you created in step 1 in the `data-sync-endpoint` attribute.

```html
<script
  src="https://transcend-cdn.com/cm/{your-bundle-id}/airgap.js"
  data-sync-endpoint="https://your-site.example/.well-known/xdi"
></script>
```

### Sync Endpoint Requirements [#sync-endpoint-requirements]

Our consent manager uses [Transcend XDI](./xdi.mdx) to facilitate consent & quarantine sync. This interface works by embedding iframes to known sync endpoints in order to construct secure tunnels for transferring sync data.

- Your consent manager's allowed domains list must include your Privacy Center domain. This is already true if your Privacy Center is on a subdomain of your primary domain (e.g. `privacy.your-site.example`)
- Your sync endpoint's embedder policy must [allow embedding by your Privacy Center](./xdi.mdx#update-embedder-policy-headers).
- Sync clients must connect from secure HTTPS origins.

### Failover [#failover]

We recommend using the following pattern to support alternative CDN failover in the event that our CDN fails to serve airgap.js.

```html
<script
  src="https://airgap-cdn.example/airgap.js"
  onerror="document.write('<script src=\'https://fallback-airgap-cdn.example/fallback-airgap.js\'></script>')"
></script>
```

This code allows your site to fallback to another airgap.js script URL if the initial request fails.

## Limitations [#limitations]

We do not support self-hosting our telemetry endpoint at this time.
