Using permalink template varaibles on pages


I have a _pages directory containing pages. I can set a permalink in a page’s frontmatter with:

permalink /page/test/

However, specifying variables doesn’t work:

slug: test
permalink /page/:slug/

(slug is one of the documented template variables)

The permalink is processed but the variable is not expanded. The above example produces literally_site/page/:slug/index.html

Ultimately I want to specify the permalink as a default in _config.yml. I have also tried that but it yields the same result - the permalink is produced but the variables are not expanded.

I am using Jekyll 3.7.0 so I should be bang up to date. I have seen other posts about this behaviour both here, GitHub and StackOverflow. They suggest this was a known issue that was resolved in earlier versions so I expect I am just doing it wrong ?

These things do work for posts. I am trying to do it for pages. How do I specify variables in a pages’ permalinks, in both frontmatter and defaults, but especially in defaults?

Further information

Having played around with this for a while, I think that variables are expanded but a limited set of variables are available. I think this set is defined by the url_placeholders function in page.rb and acceptable values are :path, :basename and :output_ext.

I have been able to test permalinks specifed in both frontmatter and the defaults config section and the one that give me the effect that I’m after is :basename.

Either frontmatter

permalink: /page/:basename/

Or defaults

    - scope:
        path: ""
        type: pages
        permalink: /page/:basename/

However… the behaviour differs between a permalink in frontmatter and one in the defaults config section. The latter causes many files to be generated, like basename iterates over feed, index, lunr-en, main, robots, sitemap as well as test which is the one that was expected.

I fixed this by expressing the defaults like this:

    - scope:
        path: "_pages"
        permalink: /page/:basename/

This works for me but I am not sure whether it is the right thing to do.


One of my theme’s users was bit by this same thing. When you set a front matter default and limit the scope to type: pages it hits every “page”.

Meaning anything with front matter that isn’t a collection (or post). That’s why you’re seeing it apply the basename to feed, index, lunr-en, etc.

You have to limit the scope to just the pages in _pages, which is what you’ve done. As far as I know that’s the correct way to go about it.


Hey @mmistakes. I’ve since found another problem which I am researching -you may have already encountered this one…

I’ve found that, with my config as shown at the end of my post, everything works UNTIL you add a paginated (v2) collection to a page. That is to say that adding frontmatter:

  enabled: true
  collection: whatever

causes the link between the page and the defaults to break. The pages return to being rendered under :basename (literally) and any other defaults (such as author_profile and layout) are ignored.

I haven’t yet a clue why this is…


Not sure on that one. If I had to guess its related to how jekyll-paginate-v2’s page generation works or when it hooks into Jekyll.

I’m not really familiar with those internals to say. Perhaps reach out to the developer of that plugin to see if they have any ideas?


Yes, I’ve created an isolated test and opened an issue at sverrirs/jekyll-paginate-v2.


Please check my patch for permalink defaults in your JPv2 issue, @johnlane. Thanks!