# Custom domain

A custom domain, such as `stats.example.com`, points to crowne. The script loads from it, and its events go to it. Blockers that block crowne's hosts by name do not block it. You need no server code.

## Set it up

1. In the app, open the site's **Settings**, then **Custom domain**.
2. Enter a subdomain of one of the site's domains, such as `stats.example.com`. Each site has one custom domain.
3. At your DNS provider, add the record that the app shows:

```text
stats.example.com.  CNAME  cname.crowne.io.
```

4. Wait for the status to show **Active**. crowne checks the record and gets a TLS certificate for the name. This usually takes a few minutes.

If your DNS is on Cloudflare, set the record to **DNS only**, not proxied.

## Use it

Load the script from your domain. Events go to the same domain.

```html
<script
  defer
  src="https://stats.example.com/v1/script.js"
  data-site="YOUR_SITE_ID"
>
</script>
```

With the [npm package](./npm.md), set `endpoint`:

```js
let analytics = crowne("YOUR_SITE_ID", {
  endpoint: "https://stats.example.com/v1/events",
});
```

## Send events to crowne

You can load the script from your domain and still send events to crowne with `data-endpoint`. There is rarely a reason to do this: a blocker that blocks `in.crowne.io` drops those events.

```html
<script
  defer
  src="https://stats.example.com/v1/script.js"
  data-site="YOUR_SITE_ID"
  data-endpoint="https://in.crowne.io/v1/events"
>
</script>
```

## Limits

A custom domain is a CNAME, and a CNAME is visible to tools that look up DNS. uBlock Origin on Firefox and DNS-level blockers look up each name. When crowne's target is on their lists, they block your custom domain too. For the strongest setup, use the [first-party proxy](./proxy.md). See [Ad blockers](./blockers.md).

To remove a custom domain, remove it in the app first, then delete the DNS record.
