# Custom Subdomain Blog Hosting (/docs/subdomain)



Use a custom subdomain when you want EarlySEO to host your blog while your main website stays exactly where it is. Your platform never changes — you add one DNS record and link to the blog from your navigation.

```text
Main website: example.com     (unchanged, on your current platform)
EarlySEO blog: blog.example.com
```

This is the recommended setup for any platform that has no publishing API, and it also works alongside platforms that do.

When to use this setup [#when-to-use-this-setup]

* Your website builder or CMS has no blog publishing API — Squarespace, Carrd, Webflow without CMS seats, custom static sites
* You want EarlySEO to host and serve the generated articles, including SSL
* You want the blog on your own domain for SEO, rather than a third-party domain
* You do not want to touch your root domain or `www` records

If your platform has a direct integration — [WordPress](/docs/wordpress), [Webflow](/docs/webflow), [Shopify](/docs/shopify), [Ghost](/docs/ghost), [Wix](/docs/wix), [Notion](/docs/notion) — publishing into that CMS is usually the better fit. Use a custom subdomain when it is not.

Prerequisites [#prerequisites]

* A domain you control, such as `example.com`
* Access to the DNS settings for that domain
* An EarlySEO account with a site created

The subdomain is always blog. [#the-subdomain-is-always-blog]

EarlySEO serves hosted blogs at `blog.` plus your root domain. You enter `example.com` and the blog is created at `blog.example.com`.

Other prefixes such as `articles.` or `insights.` are not supported. Entering `articles.example.com` produces `blog.articles.example.com`, which is almost certainly not what you want.

This integration is subdomain-only. Serving the blog from a path such as `example.com/blog` requires a reverse proxy you run yourself — see [Cloudflare Worker Setup](/docs/cloudflare-worker-setup) if that is what you need.

If you use Cloudflare, read this first [#if-you-use-cloudflare-read-this-first]

This is the single most common reason a blog subdomain fails to come up.

Cloudflare's **proxy** (the orange cloud) must be **off** for the blog record, at least until the certificate is issued. With it on:

* `blog.example.com` resolves to Cloudflare's own addresses instead of EarlySEO
* EarlySEO never gets to issue an SSL certificate for your subdomain
* Cloudflare then cannot reach us over HTTPS and shows **`SSL handshake failed` (error 525)**

Set the record to **DNS only** (grey cloud). Once the blog loads you may turn the proxy back on, but only with SSL/TLS mode set to **Full (strict)** — anything lower brings the error straight back.

EarlySEO detects this automatically. If it happens, your integration in **Integrations** will say *Cloudflare proxy is turned on* and list the steps to fix it.

Setup [#setup]

1. Create the integration [#1-create-the-integration]

1. Go to **Integrations** in your EarlySEO dashboard
2. Click **Add Integration** and select **Custom Subdomain**
3. Fill in the form:
   * **Your Domain**: your root domain, for example `example.com` — not `blog.example.com`
   * **Publishing Behavior**: choose **Publish Immediately** or **Save as Draft**
4. Click **Create Integration**

EarlySEO registers `blog.example.com` with our hosting provider at this point and shows you the DNS record to add.

> On Squarespace? Use the [Squarespace integration](/docs/squarespace) instead. It runs this same hosted blog and adds Squarespace-specific navigation steps.

2. Add the DNS record [#2-add-the-dns-record]

In your DNS provider, add a CNAME record:

```text
Type:  CNAME
Name:  blog
Value: blog.earlyseo.com
TTL:   Automatic (or 300)
```

Only add the subdomain record. Do not edit the records for `example.com` or `www.example.com` — your main website keeps resolving exactly as it does today.

The **Name** field takes only the subdomain part. Most providers append the root domain for you:

| Provider                          | Enter in the name field                |
| --------------------------------- | -------------------------------------- |
| Cloudflare                        | `blog`                                 |
| Namecheap                         | `blog` (Host field, record type CNAME) |
| GoDaddy                           | `blog`                                 |
| Squarespace Domains               | `blog`                                 |
| Google Domains / Google Cloud DNS | `blog`                                 |
| Route 53                          | `blog.example.com` (full name)         |

If your provider rejects a bare `blog`, enter the fully qualified `blog.example.com` instead.

**Cloudflare users:** set the record to **DNS only** (grey cloud) until the certificate is issued. Leaving the orange proxy cloud on during provisioning causes SSL error 525. You can enable proxying afterwards with SSL mode set to **Full (strict)**.

3. Wait for DNS and SSL [#3-wait-for-dns-and-ssl]

DNS usually propagates within a few minutes but can take up to an hour. SSL is issued automatically once the record resolves to EarlySEO — you do not need to upload or configure a certificate.

Verifying the setup [#verifying-the-setup]

1. Confirm DNS resolves [#1-confirm-dns-resolves]

From a terminal:

```bash
dig +short CNAME blog.example.com
```

On Windows:

```text
nslookup -type=CNAME blog.example.com
```

Expected result:

```text
blog.earlyseo.com
```

If you see a different target, or nothing at all, the record has not propagated yet or was saved under the wrong name.

2. Check the verification endpoint [#2-check-the-verification-endpoint]

Open this URL in a browser:

```text
https://blog.example.com/.well-known/earlyseo-verify
```

Expected result: a plain text verification token.

A `404` means the subdomain is not reaching the EarlySEO hosted-blog app yet. A certificate warning means SSL is still being issued.

3. Revalidate in EarlySEO [#3-revalidate-in-earlyseo]

Return to **Integrations** and click **Validate** on the integration. Once the verification endpoint returns the expected token, the status changes to **Connected**. Validating also retries domain registration if it did not complete the first time.

4. Open a published article [#4-open-a-published-article]

Publish an article from EarlySEO and open its URL:

```text
https://blog.example.com/my-article-slug
```

The article should render on your subdomain, styled to match your brand color. See [Article Theming](/docs/article-theming) to customize the appearance.

Troubleshooting [#troubleshooting]

**Subdomain does not resolve**

* Confirm a CNAME record exists for `blog`
* Confirm the name field holds only `blog`, not `blog.example.com`, unless your provider requires the full name
* Confirm the target is exactly `blog.earlyseo.com`, with no trailing slash or `https://`
* Wait for propagation and check again with `dig`

**Verification endpoint returns 404**

* Confirm DNS resolves to `blog.earlyseo.com`
* Click **Validate** on the integration to retry domain registration
* Wait for provisioning to finish, then retry

**`SSL handshake failed` / Cloudflare error 525** — the most common failure

* The Cloudflare proxy is on. Set the blog record to **DNS only** (grey cloud).
* Leave the value as `blog.earlyseo.com` — the target is already correct. Do **not** replace it with the address your host's dashboard suggests.
* Wait a minute, then click **Revalidate** on the integration.
* Re-enable the proxy only after the blog loads, with SSL/TLS mode **Full (strict)**.

**Cloudflare error 521, 522, or 523**

* Cloudflare cannot reach our servers. Same fix: set the record to **DNS only** and revalidate.

**SSL or certificate warning (no error code)**

* Confirm the CNAME target is `blog.earlyseo.com`
* The certificate is probably still being issued. Wait a few minutes and reload.

**Main website changed unexpectedly**

* Only the `blog` record should have been touched. Restore your root and `www` records to their previous values — the hosted blog never requires changing them

**Articles are not appearing**

* Confirm the integration shows **Connected**
* Confirm the article is published rather than saved as a draft
* Open the article URL directly from EarlySEO rather than through your navigation link

Linking the blog from your site [#linking-the-blog-from-your-site]

EarlySEO does not modify your main website. Add a navigation link yourself, pointing to:

```text
https://blog.example.com
```

Use a label such as `Blog`, `Articles`, or `Insights`. Every platform supports external navigation links — for Squarespace specifically, see the [Squarespace guide](/docs/squarespace).

Related [#related]

* [Squarespace integration](/docs/squarespace) — the same hosted blog, with Squarespace-specific navigation steps
* [Article Theming](/docs/article-theming) — brand colors and dark mode on hosted articles
* [All integrations](/docs) — direct CMS publishing options
