404 Error on Every Page in Ghost? Here's How to Fix It

404 Error on Every Page in Ghost? Here's How to Fix It

TL;DR - Check your routes.yaml file. If you've migrated from Ghost (pro) to self-hosted, you are missing vital configuration that isn't provided by Pro.

A few weeks ago, I migrated my blog from Ghost (pro) to Ghost (self-hosted). The migration mostly went smoothly, with blog posts moving over smoothly and even managing to get Mailgun set up after quite a few troubles. One that I only just fixed (oops) was that every page was 404'ing.

Don't you just love seeing this?!

The Error

The error was simple: everything was giving a 404 error in the frontend. The admin panel worked just fine, and I was able to create posts, pages, and manage my site - it just would not load the frontend. Checking the logs was completely inconclusive, Ghost would simply report a 404 error.

On a positive note, however, Ghost was serving correct redirects. Unfortunately, those redirects lead to 404 pages themselves.

The Solution

The solution was actually quite simple in the end, albeit not obvious from first glance. I eventually stumbled upon a similar forum thread from January 2022 that said:

When reviewing your site, it looks like you’re running a custom routes.yaml file, which doesn’t include the base configuration – e.g. the setup that gives tag archive pages their path on the site. The easiest fix for this would be to login to Ghost Admin, and upload the base configuration back to the site, in the Settings > Labs area (under “Routes”).
How to get to your Labs area

And, yep, that was it! My routes.yaml file, when copied over from Ghost Pro, was missing vital configuration that would otherwise normally be present. More specifically, I missed this segment:

routes:

collections:
  /:
    permalink: /{slug}/
    template: index

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

In my case, I had set up redirects from my old blog articles to their new permalinks within Ghost. So, my config looked a bit like this:

301:
  /posts: /
  /posts/2019/i-built-a-serverless-blog-in-30-minutes: /i-built-a-serverless-blog-in-30-minutes
  /posts/2019/i-wrote-the-best-php-obfuscator-as-a-joke: /i-wrote-the-best-php-obfuscator-as-a-joke
  /tags/devops: /tag/devops
  /tags/php: /tag/php
  /tags/programming: /tag/programming

This was perfectly acceptable within Ghost Pro, and pretty much every blog post on the planet will echo that. However, Self-Hosted seems to require the additional block above to work properly.

Ghost is a great platform, but unfortunately a lot of its documentation relies on the fact you're running Ghost Pro. On the other hand, for small blogs (hi!) Self-Hosted is a far better option - especially if you already have server space available.

Hope this helps someone out with their self hosting journey!