---
eleventyNavigation:
  key: UsingCustomDomains
  title: Using custom domains
  parent: CodebergPages
  order: 10
---

{% admonition "Warning" %}

Codeberg Pages has recently migrated from the legacy v2 codebase to the newer [git-pages](https://git-pages.org/) codebase.

Take note of some minor [changes and deprecations](/codeberg-pages/migrating-from-pages-v2/#breaking-changes-and-deprecations).

If you have not yet [migrated your own site to the new server,](/codeberg-pages/migrating-from-pages-v2/) we encourage you to do so.
We do not currently have any concrete plans to disable Pages Server v2.

The new documentation is work in progress, and we appreciate your feedback. Please let us know in case you find yourself confused.

{% endadmonition %}

{% admonition "Warning" %}

Codeberg Pages is currently migrating from the legacy v2 codebase to the newer [git-pages](https://git-pages.org/) codebase.

Currently, websites that use custom domains can only be deployed using the old method, but we are working to fix this.
Such websites will keep working indefinitely.
You will be able to seamlessly migrate to the new version of Pages once it is supported.
Take note of some minor [changes and deprecations](/codeberg-pages/migrating-from-pages-v2/#breaking-changes-and-deprecations).

Websites hosted under the `codeberg.page` domain can already use the new git-pages method.

The new documentation is work in progress, and we appreciate your feedback. Please let us know in case you find yourself confused.

{% endadmonition %}

Instead of using the `codeberg.page` domain, you can also purchase your own domain from a domain registrar of your choice
and configure it to serve content from Codeberg Pages.

{% admonition "warning" "Known pitfalls for failed certificate errors" %}

If you have a [CAA record](https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization#Record) configured,
you must [explicitly allow Let's Encrypt in your CAA record](https://letsencrypt.org/docs/caa/).
The value of the CAA record would look like `letsencrypt.org;accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/292520050;validationmethods=tls-alpn-01,http-01`.

If you're using [DNSSec](https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions) on your custom domain, you might run into TLS certificate issues because `codeberg.page` doesn't use DNSSec at the moment.
In this case you must add `A` / `AAAA` / `TXT` records for all domains instead of `CNAME` records. You can use [this tool](https://dnssec-analyzer.verisignlabs.com) to verify your setup.

{% endadmonition %}

_We assume for the following description, that you want to serve your website with and without www in front.
If you are on a subdomain already (like myproject.yourdomain.com), you can skip the `www.yourdomain.com` CNAME entry._

{% admonition "Warning" %}

When setting up DNS records with many registrars, any domain added to the `Domain` or `Host` option is automatically
appended onto the domain the records are being made for.

For example, if your domain is `example.com`, entering `www` will mean the record refers to `www.example.com`.

Therefore, in this guide, you may need to replace references to just your domain name (e.g. `example.com`) with `@` and
`anything.example.com` (i.e. any subdomain) with just `anything`.

{% endadmonition %}

### Step 1: CNAME, ALIAS, or A/AAAA record

The easiest and recommended way is to just setup a CNAME record for your domain, pointing to the mentioned above locations.
In the end, it should look like this:

<table class="table">
 <thead>
  <th>Domain</th>
  <th>Type</th>
  <th>Data</th>
 </thead>
 <tbody>
  <tr>
   <td>yourdomain.com</td>
   <td>CNAME</td>
   <td>codeberg.page.</td>
  </tr>
  <tr>
   <td>www.yourdomain.com</td>
   <td>CNAME</td>
   <td>codeberg.page.</td>
  </tr>
 </tbody>
</table>

{% admonition "Warning" %}

With a CNAME record everything on this domain is delegated to `codeberg.page`, which means you cannot setup your own
email address with this method.

If you need email or others services, you have to use one of the remaining options.

{% endadmonition %}

If you have an apex domain you will not be able to use a CNAME record.
In this case, many DNS providers support an ALIAS record which will work instead.

<table class="table">
 <thead>
  <th>Domain</th>
  <th>Type</th>
  <th>Data</th>
 </thead>
 <tbody>
  <tr>
   <td>yourdomain.com</td>
   <td>ALIAS</td>
   <td>codeberg.page.</td>
  </tr>
  <tr>
   <td>www.yourdomain.com</td>
   <td>ALIAS</td>
   <td>codeberg.page.</td>
  </tr>
 </tbody>
</table>

If you cannot use a CNAME nor an ALIAS record,
you will need to set up the A and AAAA records to point to Codeberg’s IP addresses directly.

It is possible these IP addresses will change in future,
so keep an eye on Codeberg updates to check.

<table class="table">
 <thead>
  <th>Domain</th>
  <th>Type</th>
  <th>Data</th>
 </thead>
 <tbody>
  <tr>
   <td>yourdomain.com</td>
   <td>A</td>
   <td>217.197.84.141</td>
  </tr>
  <tr>
   <td>yourdomain.com</td>
   <td>AAAA</td>
   <td>2a0a:4580:103f:c0de::2</td>
  </tr>
 </tbody>
</table>

### Step 2: Configure Git-pages authorization

{% admonition "question" "Why do I need all these extra DNS records?" %}

When someone tries to deploy a website to your domain,
Codeberg Pages needs to know which repository is responsible for the content,
and that the content actually comes from that repository.

When the webhook or Forgejo Action are triggered,
the server receives a token letting it know that the repository’s policies allowed the deploy.
The DNS records in turn ensure that the domain owner authorizes that repository to be deployed to that domain.

{% endadmonition %}

**If you deploy from a webhook,**
set a TXT record on the `_git-pages-repository` subdomain of your domain with the HTTPS Git clone URL for your repository.

<table class="table">
 <thead>
  <th>Domain</th>
  <th>Type</th>
  <th>Data</th>
 </thead>
 <tbody>
  <tr>
   <td>_git-pages-repository.yourdomain.com</td>
   <td>TXT</td>
   <td>https://codeberg.org/username/repository.git</td>
  </tr>
  <tr>
   <td>_git-pages-repository.www.yourdomain.com</td>
   <td>TXT</td>
   <td>https://codeberg.org/username/repository.git</td>
  </tr>
 </tbody>
</table>

**If you deploy from Forgejo Actions,**
set a TXT record on the `_git-pages-forge-allowlist` subdomain of your domain with the HTTPS Git clone URL for your repository.

<table class="table">
 <thead>
  <th>Domain</th>
  <th>Type</th>
  <th>Data</th>
 </thead>
 <tbody>
  <tr>
   <td>_git-pages-forge-allowlist.yourdomain.com</td>
   <td>TXT</td>
   <td>https://codeberg.org/username/repository.git</td>
  </tr>
  <tr>
   <td>_git-pages-forge-allowlist.www.yourdomain.com</td>
   <td>TXT</td>
   <td>https://codeberg.org/username/repository.git</td>
  </tr>
 </tbody>
</table>

### Step 3: Set your webhook or Forgejo Actions deploy target

**If you deploy from a webhook,**
the webhook **Target URL** should be set to the domain you want to deploy your website to.

**If you deploy from Forgejo Actions,**
the `site` parameter to the Git-pages action should be set to the URL of your custom domain.

### Deploying to versions of your domain both with and without `www.`

If you would like to serve your website at versions with and without a `www.` prefix,
you should choose one of them to be the ‘canonical’ URL,
add a [`_redirects` file](/codeberg-pages/advanced-usage/) to your site redirecting from one version to the other,
and deploy your website to both domains. (I.e. set up two separate webhooks, or use two separate deploy actions.)

For example, to redirect people from www.yourdomain.com to yourdomain.com,
use this `_redirects` file:

```
//www.yourdomain.com/* https://yourdomain.com/:splat 302!
```

For the redirect to work,
you should be sure that the code (here `302!`) includes an `!` at the end.
Otherwise, the redirect will only work on pages which are otherwise not found.
