If you've tried to drop ads.txt straight into your Ghost site's root folder and gotten a 404, you're not alone — it's one of the most common questions in the Ghost forums. Ghost doesn't expose a public root directory the way a typical file host or WordPress install does. Instead, ads.txt (and similar "well-known" root files) need to live inside your active theme's root folder, because that's where Ghost looks for static files when a request doesn't match a post, page, or route.

The good news: as of 2026, Ghost has a built-in in-browser theme code editor that makes this a lot less painful than the old zip-download-edit-reupload cycle. This guide covers both the new way and the fallback methods, for Ghost(Pro) and self-hosted installs.


Why abc.com/ads.txt 404s by default

Ghost's file structure isn't like a normal web server where any file you upload to the root is instantly servable. Static assets that need to live at the domain root — ads.txt, robots.txt overrides, custom verification files, etc. — are served from the root of your currently active theme, not the root of the Ghost installation. If the file isn't in the active theme, or the theme hasn't been re-activated after adding it, you'll get a 404.


Method 1: Ghost's built-in Theme Editor (new in 2026, easiest)

Ghost shipped an in-admin code editor ("Edit code") in May 2026 that lets you add, edit, rename, and delete theme files directly in the browser — no zip download, no re-upload. This is now the fastest way to get ads.txt in place.

Steps:

  1. Go to Settings → Design & Branding in Ghost Admin.
  2. Find your active theme and click Edit code (this opens a full code editor, powered by Monaco — the same editor that powers VS Code).
  3. In the file browser panel, create a new file at the root of the theme (not inside assets/, partials/, or any subfolder) named exactly ads.txt.
  4. Paste your ads.txt content — usually copied straight from your AdSense or Google Ad Manager dashboard, something like:
    google.com, pub-XXXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0
    
  5. Save. Since this edits the live active theme in place, there's no separate "upload" or "activate" step required.

This method works for both Ghost(Pro) and self-hosted sites running a recent Ghost version, since it's an Admin feature rather than a hosting-specific one. One caveat: it's a community-built, open-source tool that Ghost adopted into core, so double-check it's enabled on your version if you don't see "Edit code" as an option.


Method 2: The classic download → edit → re-upload method (fallback)

This still works everywhere, including older Ghost versions or if the in-browser editor isn't available to you.

  1. In Ghost Admin, go to Settings → Design & Branding.
  2. Under your active theme, choose Advanced → Download (or open the theme's options menu) to get a .zip of your current theme.
  3. Unzip it locally.
  4. Add an ads.txt file to the root of the unzipped theme folder — the same level as package.json and index.hbs, not inside a subfolder.
  5. Re-zip the theme folder (make sure ads.txt ends up at the top level of the zip, not nested inside an extra folder).
  6. Back in Ghost Admin, use Upload theme to upload the new zip, then activate it.
  7. Visit yourdomain.com/ads.txt to confirm it loads.

This is the method most older tutorials and forum threads describe, and it's still the one you'll need on Ghost(Pro) if custom theme uploads are available on your plan but the new editor isn't yet enabled.


Self-hosted Ghost: additional options

If you're self-hosting, you have a couple of extra routes beyond the two above.

Direct file placement

Drop ads.txt straight into your active theme's folder on disk:

content/themes/<your-theme-name>/ads.txt

Then restart Ghost so it picks up the change. This is quick, but it has a real downside: if you ever delete and reinstall the theme, or switch to a fresh copy during a major version upgrade, the file disappears and you have to redo it.

Docker volume mount (more upgrade-resistant)

If you run Ghost in Docker, a more durable approach is to mount your ads.txt file directly into the theme directory inside the container, e.g.:

/var/lib/ghost/content/themes/<theme-name>/ads.txt

Add a bind mount for that single file in your docker-compose.yml. Because it's mounted rather than baked into the theme, it survives theme reinstalls and doesn't require you to rebuild a custom theme every time Ghost ships an update.

The old Nginx workaround

Some older guides recommend adding an Nginx location block to redirect /ads.txt requests to a static file outside Ghost entirely. This was a workaround for versions where the theme-root approach broke. It's generally unnecessary today if you're on a current Ghost release and use one of the methods above — but if you're stuck on an old version and the theme-folder approach genuinely isn't working, it's a viable last resort. Just be aware it's one more moving part (your reverse proxy config) to maintain alongside Ghost itself.


Verifying it worked

  1. Visit https://yourdomain.com/ads.txt directly in a browser — you should see the raw text, not a 404 or your site's normal 404 page.
  2. Check that it's served from the domain root, not yourdomain.com/theme-name/ads.txt or similar.
  3. In Google AdSense / Ad Manager, use the "Check now" or crawler-check option on the ads.txt status page. Detection can lag — Google typically needs a day or two (sometimes up to a few days) to re-crawl and clear the warning, so don't panic if it's not instant.

Ghost(Pro) plan caveat: you need Custom Themes enabled

As of 2026, Ghost(Pro)'s plans are:

Plan Price (annual) Custom themes
Starter $18/mo ❌ Not available
Publisher $29/mo ✅ Included
Business $199/mo ✅ Included
Custom Contact sales ✅ Included

The Starter plan locks you to Ghost's built-in default theme and doesn't allow uploading or editing custom theme code — which means neither the theme editor nor the zip-upload method will work for adding ads.txt. Ad networks in general (AdSense included) are also listed as unavailable on Starter for the same reason. If you're on Starter and want to run ads, you'll need to upgrade to Publisher or above (some third-party Ghost hosts sell "custom themes" as a standalone add-on if you don't want a full plan upgrade — worth checking if you're not on Ghost's own Pro hosting).


Common problems and caveats

1. File placed in the wrong root.
The single most common mistake: putting ads.txt in the Ghost installation root instead of the theme root. Ghost's static file serving only looks in the active theme folder, so anywhere else 404s.

2. Forgetting to activate the updated theme.
With the zip method, uploading a new theme version doesn't do anything until you also activate it. If you have multiple theme versions installed, it's easy to edit the wrong copy or forget to switch the active one — always re-check "Installed themes" to confirm which version is actually live.

3. robots.txt is blocking Google's ad crawler.
This one catches people out even when everything else is correct: if you (or a "block all AI scrapers" snippet you added) blocked Google's advertising bot in your robots.txt, AdSense can fail to detect a perfectly valid, correctly placed ads.txt file. If your file is confirmed to exist at the right URL but AdSense still reports it missing after several days, check your robots.txt for any rule disallowing Google's ad-related user agents and remove it.

4. Theme updates can silently wipe the file.
If you installed ads.txt by editing a copy of an official theme (like Casper or Source), updating to a newer official theme version later will overwrite your custom copy unless you remember to re-add the file. This is exactly the scenario the Docker volume-mount method or a small custom child theme is meant to avoid on self-hosted installs.

5. Nested folders in the zip.
When re-zipping a theme manually, it's easy to end up with the theme's files nested one level too deep (e.g., theme-name/theme-name/ads.txt) if your zip tool wraps the folder. Ghost will usually reject an improperly structured zip, but double-check the file sits at the top level before uploading.

6. Propagation delay.
Even with everything correctly configured, Google Ad Manager / AdSense doesn't re-crawl instantly. Give it a couple of days before assuming something is broken.


Quick checklist

  • [ ] ads.txt is at the theme root, not the Ghost install root
  • [ ] The theme containing it is the currently active theme
  • [ ] yourdomain.com/ads.txt loads the raw text in a browser (no 404)
  • [ ] robots.txt doesn't block Google's ad crawler
  • [ ] You're on a Ghost(Pro) plan that supports custom themes (Publisher or above), or self-hosting with theme/file access
  • [ ] You've given AdSense/Ad Manager a day or two to re-check before troubleshooting further

Sources