---
title: "Custom domains"
description: "Serving your blog from your own hostname: the DNS record, the status transitions, and why apex domains are not supported."
updated: "2026-08-28"
verifiedAgainst:
  - packages/shared/src/domains.ts
  - packages/shared/src/free-grant.ts
  - packages/shared/src/index.ts
  - docs/custom-domain-runbook.md
---

A custom domain serves your blog from a hostname you own, for example
`blog.yourcompany.com`.

<Callout variant="note" title="Not included in the Free grant">
  Custom domains are a paid-only feature. A Free Project publishes to its
  `blogged.dev` address and cannot connect a hostname of its own. On a Free
  Project the request is refused with an upgrade prompt rather than a quota
  message, and upgrading that exact Project turns it on without losing any work.
  See [your blogged.dev address](/blog/subdomain).
</Callout>

## Adding one

<Steps>
  <Step title="Add the domain in Project settings">
    Settings, then Domain. Enter the hostname you want to use.
  </Step>
  <Step title="Create a CNAME record at your DNS provider">
    Point the hostname at the target Blogged gives you.

    ```txt
    Type:   CNAME
    Name:   blog
    Value:  verify-<your unique value>.blogged.dev
    TTL:    3600 or automatic
    ```

    Copy the exact target shown in Domain settings. Each claim gets its own
    target, so a target copied from another domain or an older attempt will not
    verify. No additional TXT record is required.

  </Step>
  <Step title="Wait for verification">
    Blogged checks the record. This takes as long as your DNS provider takes to
    propagate, usually minutes.
  </Step>
  <Step title="Wait for the certificate">
    A certificate is issued automatically once the record verifies. Nothing to do
    here.
  </Step>
</Steps>

## Status

| Status        | Meaning                                                                                |
| ------------- | -------------------------------------------------------------------------------------- |
| `pending_dns` | Waiting for the CNAME record to be visible                                             |
| `pending_ssl` | Record found, certificate being issued                                                 |
| `active`      | Serving                                                                                |
| `error`       | Something is wrong. The reason is shown with it                                        |
| `expired`     | The ownership-verification window ended; select **Start fresh setup** for a new target |

## Apex domains are not supported

<Callout variant="warning" title="Use a subdomain, not the root">
  `blog.yourcompany.com` works. `yourcompany.com` does not. DNS does not permit a CNAME at the root
  of a zone alongside the records that make email and name resolution work, and the workarounds
  registrars offer for it are not portable between providers.
</Callout>

## Primary and alias

A blog can carry more than one hostname, one of which is primary. The primary is
the canonical address: it is what appears in your sitemap, in canonical tags and
in links. Aliases resolve to the same content without competing with it in
search.

## If verification does not complete

- Check the record type is CNAME, not A.
- Check there is no conflicting record on the same name.
- If your DNS provider proxies traffic, the proxy has to be off for verification.
- Give it an hour. Some providers are slow rather than broken.
- If the claim expired or predates claim-specific targets, select **Start fresh setup**. Blogged keeps the hostname reservation and gives you a new CNAME target without deleting the domain.
