> For the complete documentation index, see [llms.txt](https://docs.xenoraa.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xenoraa.com/xenoraa-super-admin-operations-manual/custom-domain-mapping-and-routing.md).

# Custom Domain Mapping & Routing

## Custom Domain Mapping & Routing

Xenoraa is a multi-tenant platform where tenants can access their workspaces via a subdomain (e.g., `tenant.xenoraa.com`), a subfolder (e.g., `xenoraa.com/tenant`), or a completely custom domain (e.g., `tenantcustomdomain.com`). Managing custom domains requires coordinated configuration in the Super Admin panel, Cloudflare DNS, and the server's Nginx configuration.

***

### 1. Domain Routing Architecture

When a request arrives at the server, the `TenantContext` middleware inspects the host header:

1. If the host is `xenoraa.com` or `localhost`, it routes to the main marketing page or checks the subfolder prefix.
2. If the host matches an approved custom domain in the `users` table (`custom_domain` column), it automatically sets that user's ID as the active tenant context.

```
Incoming Request (apexretail.com) 
  ──> Cloudflare (Proxy/SSL) 
    ──> Nginx Server (Vhost) 
      ──> TenantContext Middleware (matches user_id) 
        ──> Tenant Workspace Live!
```

***

### 2. Step-by-Step Domain Mapping Workflow

To map a custom domain for a tenant, follow this exact 4-step workflow:

#### Step 1: Tenant Submits Request

The tenant enters their custom domain (e.g., `apexretail.com`) in their workspace settings page. This adds the domain to their user record with `custom_domain_status = 'pending'`.

***

#### Step 2: Tenant Configures DNS (CNAME or A Record)

Instruct the tenant to add the following record in their DNS registrar (GoDaddy, Namecheap, etc.):

| Record Type  | Host           | Value / Target      | Description                                                              |
| ------------ | -------------- | ------------------- | ------------------------------------------------------------------------ |
| **CNAME**    | `@` (or `www`) | `cname.xenoraa.com` | Recommended for subdomains or registrars supporting CNAME flattening.    |
| **A Record** | `@`            | `69.62.75.225`      | Required if their registrar does not support CNAME on root apex domains. |

***

#### Step 3: Super Admin Approves Domain & Configures Cloudflare

Once the tenant configures their DNS, you must add the domain to the Xenoraa Cloudflare zone to enable SSL proxying.

1. Navigate to **Custom Domains** (`/superadmin/domains`).
2. Locate the pending request and click **Verify DNS**. The system will run a dig query to check if their domain points to our IP.
3. Open the **Cloudflare Dashboard** (`dash.cloudflare.com`) for `xenoraa.com`.
4. Go to **DNS Settings** and add an **A Record** or **CNAME** mapping their domain to our server. Ensure the **Proxy Status** is set to **Proxied** (orange cloud) to enable SSL and WAF protection.
5. Go back to the Super Admin panel and click **Approve Domain**. This sets `custom_domain_status = 'approved'`.

***

#### Step 4: Rebuild Nginx Configuration (If Applicable)

Our Nginx server uses a catch-all block (`server_name .xenoraa.com;`) which automatically handles any domain pointing to the server IP. However, if the tenant's domain requires custom Nginx rules (e.g., specific redirect or header overrides):

1. SSH into the server as root: `ssh root@69.62.75.225`.
2. Navigate to Nginx vhosts: `cd /etc/nginx/sites-available/`.
3. Create a custom block or ensure the main catch-all block is running correctly:

   ```nginx
   server {
       listen 443 ssl http2;
       server_name apexretail.com www.apexretail.com;
       root /var/www/gopi.blog/gopi-portfolio/public;
       index index.php;
       # ... standard Laravel SSL config ...
   }
   ```
4. Test configuration: `nginx -t`.
5. Reload Nginx: `systemctl reload nginx`.

***

### Domain Status Reference

You can monitor and filter domain requests on the Custom Domains page (`/superadmin/domains`) using these statuses:

| Status           | Meaning                                                              | Super Admin Action Required                                  |
| ---------------- | -------------------------------------------------------------------- | ------------------------------------------------------------ |
| **Pending**      | Tenant requested domain, DNS not yet verified.                       | Wait for tenant to configure DNS, then click **Verify DNS**. |
| **DNS Verified** | Domain points to our server IP successfully.                         | Add to Cloudflare, then click **Approve Domain**.            |
| **Approved**     | Domain is fully active and routed to the tenant workspace.           | None. Domain is live.                                        |
| **Rejected**     | Domain request was denied (e.g., invalid domain or terms violation). | None. Tenant can request a different domain.                 |
| **Suspended**    | Domain is blocked due to tenant subscription suspension.             | Reactivate tenant subscription to restore domain routing.    |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.xenoraa.com/xenoraa-super-admin-operations-manual/custom-domain-mapping-and-routing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
