How to Create URL Subdirectories in Ghost

Subdirectories help you group content by subject matter and allow users to find additional information on your site about topics they are interested in.

Ghost makes it easy to create subdirectories.

Here’s an overview of the process:

  1. Create an internal tag.
  2. Create a collection in routes.yaml using that internal tag.
  3. Create posts and tag them with the new tag.
  4. Update your theme to list posts with that tag (optional).


Ghost Posts vs Pages

It may seem like we should be using pages (in the Ghost terminology) instead of using posts since the resulting posts are completely different from the usual blog articles.   This is really just a terminology issue.  A ‘post’ in Ghost is a generic piece of content and the collection it lives in really determines what it is.  Pages are just special cases of posts that are outside of a collection and are therefore only useful for special cases (like the home page).

Create an internal tag

Internal tags are used for content organization outside of the standard /tags/ hierarchy.  We’ll create an internal tag to indicate which posts are shown under the /content/ subdirectory.

Internal tags created like regular tags but begin with a hash (#) symbol.  Go to the Tags page of the Ghost admin dashboard and create a new tag:

Ghost with no internal tags
Create new tag in Ghost

The name has to begin with a hash sign so we’ll use #compare.   You can leave everything else blanks for now and just hit Save.  After saving the tag, note that the slug is auto populated as hash-compare – this value will be used to filter our collection.

Create a collection

A collection in Ghost is just a group of associated content.  Content can only live in one collection so if you add posts to a collection they will automatically be excluded from later collections.  This means that after we are done, any posts that appear under /compare/ will not appear under /blog/.

Collections are defined via the routes.yaml file.  Download your routes.yaml file via the ‘Labs’ section in the Ghost admin dashboard.

routes.yaml in Ghost

Add a section under the ‘collections’ section indicating where you want the posts to appear – in our case under /compare/.

    data: page.home
    template: home

    permalink: /compare/{slug}/
    filter: tag:hash-compare
    permalink: /blog/{slug}/

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

Save your changes and upload the resulting file.  Don’t worry about breaking anything, if there is an error Ghost will warn you and not accept the file.

Tag Posts

Tag each comparison post with the #compare tag and don’t use that tag for any other purpose.  Those tagged posts will now show up under /compare/ and no where else. Adding new posts to this subdirectory will be easy – simply tag them.

Update your theme (optional)

Since the subdirectory is now its own collection, you’d need some way to link to your posts.  One approach is to just hard-code the post permalink – similar to what you have to do with a Ghost page – but a better approach is to use the Ghost API.  Using the API ensures that content you add later automatically shows up where it’s supposed to without you having to remember to add it manually.

A typical footer in Ghost lists all the pages for a given internal tag.  The list of posts is automatically generated by the Ghost theme via the following:

<h5 class="text-uppercase">Comparisons</h5>
<ul class="list-unstyled">
    {{#get "posts" limit="all" filter="tag:hash-compare" order="published_at asc"}}
        {{#foreach posts}}
            <li><a href="{{url}}">{{title}}</a></li>

The posts are ordered by publish date since we tend to write the most important ones first, but you can use any filters you want.


Organizing your content by subdirectory might not be the most intuitive in Ghost, but is very important from an SEO perspective.  We’ve seen how to use a Ghost collection and tags to make certain posts exclusively appear in a path subdirectory.  Finally, we saw how to update our theme to automatically list our subdirectory posts without having to hard-code links.