Ghost Advanced Configuration — Custom routes.yaml, Redirects and Collections
In this tutorial, you'll learn advanced Ghost configuration — creating custom routes.yaml files for granular URL control, configuring redirects for moved content, building dynamic collections with filters, and managing custom templates for different content sections.
What You'll Learn
- The routes.yaml file structure and syntax
- Creating custom routes for specific templates
- Dynamic collections with tag filters and custom permalinks
- Redirects configuration for URL changes
- Custom templates for routes and collections
- Advanced filtering with Ghost filter syntax
- Taxonomies and custom URL patterns
- Multiple RSS feeds for different collections
- routes.yaml best practices and debugging
Why It Matters
By default, Ghost serves all posts at /slug/ and tags at /tag/slug/. That works for simple blogs, but as your site grows, you need more sophisticated URL structures — a news section at /news/, a tutorial collection at /guides/ with posts at /guides/post-slug/, a featured section at /picks/, and redirects for old URLs. routes.yaml gives you complete control over your site's URL architecture.
Real-World Use
A magazine site uses routes.yaml to create three sections: /news/ (daily articles, post URLs at /news/slug/), /features/ (long-form, post URLs at /features/slug/), and /opinion/ (editorials, post URLs at /opinion/slug/). Each section has its own RSS feed, its own template with different styling, and its own tag filter. The site also redirects /old-blog/ to /news/ to preserve SEO value from their previous URL structure.
Learning Path
flowchart LR A["Performance Optimization"] --> B["Advanced Configuration
You are here"]:::current B --> C["Database Management"] C --> D["Upgrading Ghost"] classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px
The routes.yaml Structure
routes.yaml lives at content/settings/routes.yaml.
Three Sections
routes:
# Individual URL → template mappings
collections:
# Content collections with custom permalinks
taxonomies:
# Override default tag/author URL patterns
Custom Routes
Routes map a single URL to a template, optionally with content filtering.
Static Routes
Serve a specific template at a specific URL:
routes:
/about/:
template: page-about
data: page.about
/contact/:
template: page-contact
data: page.contact
This renders the page-about.hbs template at /about/, populated with content from the Ghost page with slug "about."
Channel Routes
Create paginated content listings:
routes:
/featured/:
template: featured
controller: channel
filter: featured:true
limit: 12
/popular/:
template: popular
controller: channel
order: count.posts desc
limit: 20
Route Options
| Option | Description |
|---|---|
template |
Handlebars template to render (without .hbs) |
controller |
channel for listings; omit for single pages |
filter |
Ghost filter syntax for content selection |
limit |
Items per page (default 5, max 100) |
order |
Sort order for content |
data |
Specific page or post to populate the template |
Collections
Collections create URL prefixes with custom permalinks for individual posts.
Basic Collections
collections:
/news/:
permalink: /news/{slug}/
template: index
filter: tags:[news]
limit: 10
/tutorials/:
permalink: /tutorials/{slug}/
template: tutorials
filter: tags:[tutorial]
limit: 6
Collection with Date-Based Permalinks
collections:
/blog/:
permalink: /blog/{year}/{month}/{slug}/
template: index
filter: tags:-[internal]
limit: 10
Advanced Collection
collections:
/podcast/:
permalink: /podcast/{slug}/
template: podcast
filter: tags:[podcast]
order: published_at desc
limit: 12
data: page.podcast-landing
Collection Options
| Option | Description |
|---|---|
permalink |
URL pattern for individual posts in the collection |
template |
Template for the collection listing page |
filter |
Content filter |
limit |
Posts per page |
order |
Sort order |
data |
Optional page data for the collection landing |
Taxonomies
Override the default URL patterns for tags and authors.
taxonomies:
tag: /topic/{slug}/
author: /writer/{slug}/
This changes:
/tag/<a href="/programming-languages/javascript/">JavaScript</a>/to/topic/javascript//author/jane/to/writer/jane/
Redirects
In routes.yaml
Add redirects directly in routes.yaml:
routes:
/old-url/: /new-url/
/legacy-post/: /blog/legacy-post/
Separate redirects.yaml
Create a content/settings/redirects.yaml file for larger redirect lists:
301:
/old-about/: /about/
/category/*: /blog/:splat/
/2023/: /archive/2023/
302:
/temporary-link/: /new-location/
Redirect Types
- 301: Permanent redirect (passes SEO value)
- 302: Temporary redirect (does not pass SEO value)
Custom Template Naming
Ghost looks for templates in this order:
- Exact match:
{template}.hbsas specified in routes.yaml - Fallback:
index.hbsif the specified template does not exist - Error: If no template is found, Ghost returns an error
Custom Templates for Pages
If you have a page with slug "about," create page-about.hbs and Ghost uses it automatically without routes.yaml.
Custom Templates for Routes
For a route /featured/ with template: featured, create featured.hbs in your theme root.
RSS Feeds for Collections
Each collection automatically generates an RSS feed:
/news/rss/
/tutorials/rss/
/podcast/rss/
This lets subscribers follow specific sections independently.
Example: Magazine Site
routes:
/editors-picks/:
template: picks
controller: channel
filter: featured:true
limit: 10
/about/:
template: page-about
data: page.about
collections:
/news/:
permalink: /news/{slug}/
template: index
filter: tags:[news]
limit: 10
/features/:
permalink: /features/{slug}/
template: features
filter: tags:[feature]
limit: 8
/opinion/:
permalink: /opinion/{slug}/
template: index
filter: tags:[opinion]
limit: 10
taxonomies:
tag: /topic/{slug}/
Common Mistakes
Forgetting to restart Ghost after editing routes.yaml: Changes to routes.yaml do not take effect until Ghost is restarted. Run
ghost restartafter every edit. Some changes may requireghost reloadinstead.Creating conflicting routes: If you define
/news/as a collection and also have a post or tag with the slug "news," there will be a conflict. Ghost prioritizes routes.yaml definitions over content slugs.Using incorrect filter syntax: The filter parameter uses Ghost-specific syntax (e.g.,
tags:[news]nottag:news). Incorrect filters silently return empty collections. Test filters using the Content API first.Not providing templates for custom routes: If your routes.yaml references
template: featuredbut there is nofeatured.hbsin your theme, Ghost falls back toindex.hbs. Ifindex.hbsis also missing, the route returns an error.Overcomplicating the URL structure: A simple /slug/ structure is often best for SEO. Deep nesting (/section/subsection/post-slug/) does not provide SEO benefits and makes URLs harder to share and remember.
Practice Questions
What are the three sections of routes.yaml? Answer: routes (single URL → template mappings), collections (content groups with custom permalinks), and taxonomies (override default tag/author URL patterns).
How do you create a custom RSS feed for a specific collection? Answer: Define a collection in routes.yaml. Ghost automatically generates an RSS feed at the collection URL + /rss/ (e.g., /news/rss/). Feeds are created for all collections and channel-type routes.
What happens when a route in routes.yaml conflicts with a content slug? Answer: Ghost gives priority to routes.yaml definitions. If you define /news/ as a collection, any post or tag with the slug "news" will be inaccessible at that URL. Plan your routes.yaml to avoid conflicts with content slugs.
Challenge: Design a complete routes.yaml for a multi-section publication. Include: a featured picks channel at /picks/, a news collection at /news/ with daily permalinks, a tutorials collection at /guides/ with guides at /guides/{slug}/, custom taxonomy URLs at /topic/{slug}/, and 301 redirects from old blog URLs to new sections.
FAQ
Mini Project
Your task: Create a complete routes.yaml configuration for a production Ghost site.
- Design the URL structure for a publication with 3 sections: News, Features, Podcast.
- Create routes.yaml with collections for each section, custom permalinks, and template mappings.
- Create the corresponding Handlebars template files (news.hbs, features.hbs, podcast.hbs).
- Add custom taxonomy URLs.
- Create redirects for 5 old URLs to new locations.
- Test each URL works correctly.
- Document the routing configuration for future reference.
This exercise gives you complete control over your Ghost site's URL architecture.
What's Next
Now that routing is configured, learn about database management:
Continue to Lesson 36: Database Management — SQLite vs MySQL, backups, and maintenance.
Related lessons:
- Upgrading Ghost — Safe upgrade procedures
- Security — Hardening and protection
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro