---
title: Custom Domains
description: Assign WGW subdomains and external hostnames to wgw-deploy projects.
---

# Custom Domains

Every project starts with a generated WGW domain:

```text
https://<project-slug>.wgw.lol/
```

Use `--domain` to replace it with a named WGW subdomain or an external hostname. Use the same `--cwd` and `--dir` you used for the deploy so the CLI targets the same project.

## WGW subdomains

Pass a bare name or the full `wgw.lol` hostname.

```bash
npx wgw-deploy --domain launch-preview
npx wgw-deploy --domain launch-preview.wgw.lol --json
```

Both commands assign:

```text
https://launch-preview.wgw.lol/
```

Pinned revisions for WGW domains use the revision in the hostname:

```text
https://launch-preview--26704cb219eb67f3.wgw.lol/
```

WGW subdomain rules:

- Bare names are normalized to `<name>.wgw.lol`.
- The name must be one DNS label, not nested labels.
- Use lowercase letters, digits, and hyphens.
- The name must be 4 to 63 characters.
- It cannot start or end with a hyphen.
- Reserved names such as `www`, `cname`, `x`, `api`, `admin`, `login`, `app`, `assets`, `cdn`, `mail`, `status`, and `deploy` are rejected.

The server checks whether the requested WGW hostname currently returns `404`. If it does not, the request fails with `domain already assigned`.

## External hostnames

Assign the hostname:

```bash
npx wgw-deploy --domain docs.example.com --json
```

The JSON output includes the CNAME target:

```json
{
  "projectSlug": "bright-field-mqstr7zz",
  "productionUrl": "https://docs.example.com/",
  "projectHash": "4d0c...",
  "revisionId": "26704cb219eb67f3",
  "revisionUrl": "https://docs.example.com/_rev/26704cb219eb67f3/",
  "dns": {
    "type": "CNAME",
    "name": "docs.example.com",
    "value": "cname.wgw.lol"
  }
}
```

Create this DNS record at your DNS provider:

```text
CNAME docs.example.com -> cname.wgw.lol
```

For an apex domain such as `example.com`, your DNS provider must support CNAME flattening, ALIAS, or an equivalent record that targets `cname.wgw.lol`.

External pinned revisions use the `_rev` path:

```text
https://docs.example.com/_rev/26704cb219eb67f3/
```

External domains are created through Cloudflare Custom Hostnames with HTTP domain validation. The CLI returns the CNAME target; it does not print separate certificate validation records.

## Removing a domain

Remove the assigned custom domain and return to the generated WGW domain:

```bash
npx wgw-deploy --delete-domain
npx wgw-deploy --cwd /path/to/app --dir build --delete-domain --json
```

Example JSON output:

```json
{
  "projectSlug": "bright-field-mqstr7zz",
  "productionUrl": "https://bright-field-mqstr7zz.wgw.lol/",
  "projectHash": "4d0c...",
  "revisionId": "26704cb219eb67f3",
  "revisionUrl": "https://bright-field-mqstr7zz--26704cb219eb67f3.wgw.lol/"
}
```

If the removed domain was external, WGW Deploy deletes its Cloudflare Custom Hostname record.

## Practical notes

- Assigning a domain updates existing deploy manifests when the project has already been deployed.
- Assigning a WGW subdomain or external hostname removes the project metadata expiration while that domain is assigned.
- Deleting the assigned domain resets the project to its generated WGW domain and starts a fresh 7-day metadata expiration.
- Re-running `--domain` with the currently assigned domain is idempotent.
- Re-running `--delete-domain` after the project is already on its generated WGW domain is idempotent.
- Use `npx wgw-deploy --list --json` to confirm which local project state you are about to change.
