eleventy: Pagination links break when using eleventyComputed to write permalinks in *.11ty.js templates

Describe the bug Using eleventyComputed to write permalinks in *.11ty.js templates, as described in #1076, does not produce the expected pagination links.

To Reproduce Steps to reproduce the behavior:

  1. 📋 Clone the eleventy-dot-js-blog starter project to a soon-to-be-bug-ridden project directory and install node packages locally:
git clone git@gitlab.com:reubenlillie/eleventy-dot-js-blog.git buggy-eleventy-dot-js-blog
cd buggy-eleventy-dot-js-blog
npm install 
  1. Test that the local development environment is working. Specifically, 👀 note the following paginated output from ./content/pages/archive.md:
npx eleventy --serve
…
Writing _site/blog/index.html from ./content/pages/archive.md.
Writing _site/blog/page-1/index.html from ./content/pages/archive.md.
…

Also, notice how these same pagination navigation links appear in the markup when browsing 🌎 http://localhost:8080/blog/. The Markdown/Liquid–Nunjucks front matter permalinks work. 👌

  1. 📝 Rename ./content/pages/archive.md from Markdown to a JavaScript template and translate its content:
mv content/pages/archive.md content/pages/archive.11ty.js
vim content/pages/archive.11ty.js

NB: code updated on January 19, 2021 since the starter kit now supports ES modules

// JavaScript-ified ./content/pages/archive.11ty.js
/**
 * @file Defines the chained layout for the archive page
 * @see {@link https://www.11ty.dev/docs/layouts/#layout-chaining Layout chaining in 11ty}
 */

/**
 * Acts as front matter in JavaScript templates
 * @see {@link https://www.11ty.dev/docs/languages/javascript/#optional-data-method Optional `data` in JavaScript templates in 11ty}
 */
export var data = {
  title: '📔 A Blog for the Ages',
  navTitle: '📔 Blog',
  tags: 'nav',
  weight: 3,
  layout: 'layouts/archive',
  templateEngineOverride: '11ty.js',
  pagination: {
    data: 'collections.posts',
    size: 3,
    alias: 'posts',
    reverse: true,
  },
  eleventyComputed: {
    permalink: data => `${data.site[data.locale].postsArchive.url }/${data.pagination.pageNumber > 0
      ? `page-${data.pagination.pageNumber}/` 
      : ''}index.html`
  }
}

/**
 * The archive page content
 * @method
 * @name render()
 * @param {Object} data 11ty’s data object
 * @return {String} The rendered template
 */
export function render(data) {
  return `<!-- ${data.page.inputPath} -->
This is your blog landing page. 🛬`
}
  1. Run 🧪 npx eleventy --serve again. This time, notice how the output files in the command line interface remain unchanged 😃. But, … also notice how in the browser, the pagination navigation links now render as http://localhost:8080/{{page.fileSlug}}/ 🐛. The proper routes are output by the new JavaScript template, but the pagination navigation is different.

  2. 🤔 These strange pagination navigation links resemble the permalink rules in ./content/pages/pages.11tydata.js. So, it would seem like the logical next step is to update those to eleventyComputed syntax too 🤷‍♂️:

// Updated ./content/pages/pages.11tydata.js
/**
 * @file Contains data common to all pages, to reduce repetition
 */

/**
 * Directory data module for pages
 * @module content/pages
 * @see {@link https://www.11ty.dev/docs/data-template-dir/ Template and directory data files in 11ty}
 * @see {@link  https://www.11ty.dev/docs/permalinks/ Permalinks in 11ty}
 */
module.exports = {
  layout: 'layouts/page',
  // Note: The permalink value uses Nunjucks/Liquid syntax;
  // a future version of 11ty may allow for JavaScript template literals
  // permalink: '/{{page.fileSlug}}/index.html',
  // Comment out this line ⬆️; add this basically equivalent eleventyComputed object ⬇️
  eleventyComputed: {
    permalink: data => `/${data.page.fileSlug}/index.html`
  },
  tags: [
    'pages'
  ]
}
  1. Except, this time, if you run npx eleventy --serve, notice how the output has changed 🪲:
…
Writing _site/blog/index.html from ./content/pages/archive.11ty.js. 🤤
…
Writing _site/blog/page-1/1/index.html from ./content/pages/archive.11ty.js. 🤨
…

And, in the markup, the pagination navigation links are now http://localhost:8080/content/pages/archive/ and http://localhost:8080/content/pages/archive/1/ accordingly, which look more like real pages, but they don’t exist in the output 🐜. That is, both the output and the pagination navigation links are broken after basically exchanging 💱 Markdown/Liquid–Nunjucks for Eleventy-topped vanilla JavaScript.

Expected behavior The output and pagination navigation links should match, and eleventyComputed should continue to be unquestionably awesome.

Environment:

  • OS and Version: Ubuntu 20.04.1 LTS
  • Eleventy Version: v0.11.1

Additional context

The pagination navigation is generated from ./_includes/shortcodes/pagination-nav.js. It’s a built-out version of what I prepared for the Eleventy docs. If you console.log(data.pagination) somewhere in the return statement for any of steps 3–6 above, you can verify the mutations to that object. But I’ve got no clue why the permalinks are behaving this way with pagination.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 17 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I think, problem is here: https://github.com/11ty/eleventy/blob/26bf0473ae98acac7b90f229e38b6d4dfb8f29a9/src/Plugins/Pagination.js#L184-L187

I found a hack:

  permalink: '/',

  eleventyComputed: {
    permalink: function(data) {
      return `/${data.article.fileSlug}/`
    }
  }

Possible fix:

if (pageNumber > 0 && !(this.data[this.config.keys.permalink] || this.data.eleventyComputed[this.config.keys.permalink])) { 
 cloned.setExtraOutputSubdirectory(pageNumber);
}

@Ryuno-Ki, I created a separate branch core-#1555 if you’d like to check it out. I also pushed the full DEBUG output to ./debug.txt on that branch.

Line 144 looks ‘correct’ – i.e. what I’d expect…

Eleventy:Template Rendering permalink for './src/category.11ty.js': /api/categories/category-number-two.json becomes '/api/categories/category-number-two.json' +1ms

Line 202 however has an unexpected /1/:

Eleventy:Template dist/api/categories/1/category-number-two.json written.. +0ms