routes.yaml in Ghost CMS: A Practical Guide to Dynamic Routing
Ghost gives you a lot of control over how your site is structured. Most of that control lives in a single file: routes.yaml. If you have never touched it, your site runs on Ghost’s default setup, which works fine for a standard blog. The moment you want multiple content sections, custom URL patterns, or filtered content streams, you need to understand how dynamic routing actually works.
What routes.yaml Does in Ghost
Ghost's dynamic routing system maps URL patterns to content and templates. The routes.yaml file is where all of that lives. Every new Ghost install comes with a default version already in place at content/settings/routes.yaml. You can edit it directly on the server or manage it entirely through the admin panel.
The default configuration looks like this:
routes:
collections:
/:
permalink: /{slug}/
template: index
taxonomies:
tag: /tag/{slug}/
author: /author/{slug}/
Simple enough. But the real value comes when you start customizing it. Most sites that look structurally different from a standard Ghost blog got there through this file.
The Three Sections That Control Everything
Ghost’s routing file is built around three distinct blocks, each controlling a different layer of your site.
Routes handle individual static pages or custom channels. A channel is a filtered, paginated stream of posts that does not affect the post’s own URL. Think of it as a permanent search result: you get a content archive at a custom path, without moving anything. Channels are useful when you want to surface a content subset under a new URL without restructuring your permalinks.
Collections are where the structural work happens. A collection is a group of posts with its own URL pattern and optional filter. The catch: posts can only belong to one collection at a time. They are assigned top to bottom in the file, so collection order matters more than most people expect. Put your filtered collections first. A catch-all collection at the top will absorb everything before your filters ever run.
Taxonomies define URL patterns for tags and authors. The defaults cover most sites. You can adjust them if your Ghost URL structure requires it, though changing these on a live site without setting up redirects will break existing links.
How to Access and Edit the File
Open Ghost Admin, go to Settings, then Labs. You will find a Routes section with two options: download the current file or upload a new one.
Download it, edit locally in any plain text editor, then upload it back. Ghost applies changes immediately without a restart. Editing the file directly on the server does require a restart. For most people, the admin upload route is faster and safer.
Worth knowing: YAML is sensitive to indentation, and tabs will break the file. Use two spaces only. The official Ghost routing docs are explicit about this: the most common reason a routes.yaml file fails silently is a stray tab or misaligned space. Keep a close eye on it, especially when copying examples from the web.
If you are working on a local Ghost install and want to test routing changes safely before pushing them live, our guide on installing Ghost CMS locally walks through the full setup.
Building Multiple Collections
Here is where Ghost dynamic routing earns its place. Suppose you run a publication with a daily news section alongside long-form editorial content. Each section needs its own URL structure and template.
routes:
collections:
/daily-news/:
permalink: /daily-news/{slug}/
filter: primary_tag:daily-news
template: daily-news
/:
permalink: /{slug}/
template: index
taxonomies:
tag: /tag/{slug}/
author: /author/{slug}/
The daily-news collection runs first and pulls in posts where the primary tag is daily-news. Everything else falls into the default collection at /. Reverse that order and the default collection absorbs everything, leaving the filtered one empty.
For most publishers using this setup, this is exactly where I would start. It is straightforward to debug, easy to extend, and covers the majority of multi-section use cases without overcomplicating the file.
Passing Data to Collections and Routes
Both routes and collections accept a data property. This is how you attach a Ghost page or tag object to a collection, which lets you set a custom meta title, description, and feature image for section pages. Without it, Ghost falls back to site-level defaults.
collections:
/blog/:
permalink: /blog/{slug}/
template: blog
filter: tag:blog
data: tag.blog
That data: tag.blog line pulls the tag object for blog and makes it available to the template. Your blog.hbs file can then use the tag’s name and description as the section’s metadata. It is a small addition that makes a meaningful difference for SEO on high-traffic archive pages.
Channels vs. Collections: When to Use Each
The distinction trips people up regularly, so it is worth being direct about it.
A collection controls where a post lives. It sets the permalink. A post in your /podcast/ collection lives at /podcast/my-episode/. That is its home.
A channel does not move anything. It creates a filtered archive at a path, but posts keep whatever URL their collection assigned them. Use channels when you want to expose a curated content stream without changing your existing URL structure. A newsletter archive that pulls posts tagged newsletter without reassigning their URLs is a good channel use case.
Ghost's tutorial on content collections covers practical examples of both patterns if you want to go deeper.
Who Should Use Custom routes.yaml
You run a multi-topic publication
If your site covers distinct content areas, separate Ghost CMS collections let each area have its own URL structure and template. That is cleaner than managing everything through tags and trying to filter after the fact at the theme level.
You want a custom homepage
Setting your homepage to something other than a reverse-chronological post list requires a route definition. You point / at a static page or a custom template. This is one of the most common Ghost customizations, and the file is the right place to do it:
routes:
/: home
collections:
/blog/:
permalink: /blog/{slug}/
template: index
You are distributing a Ghost theme
If your theme depends on a custom routes.yaml, users need to upload that file separately after installing the theme. It does not come bundled in the theme zip. That detail is easy to miss. If you are releasing a theme publicly, document it clearly. Our guide on installing a theme in Ghost CMS explains the upload process step by step, which is useful context to link users to.
A Note on Redirects
Changing your Ghost URL structure does not automatically redirect old paths. If you restructure an existing site, a redirects.yaml file handles the legacy URLs. Ghost supports both files independently. Skipping the redirect step means broken links and lost search rankings on pages that already have backlinks or traffic. Plan for both files before touching routing on a live site.
Check the renewal price before signing up for any managed Ghost host that promotes easy routes.yaml support. The upload interface is standard across all installs, managed or self-hosted. It is not a differentiating feature worth paying a premium for.
Download your current file, make one small change, and test it before going further. Incremental edits are faster to debug than a complete rewrite of the file.