Skip to content

fix(preset-eleventy): write posts where the advertised URL resolves - #916

Draft
rmdes wants to merge 1 commit into
mainfrom
fix/eleventy-post-url-matches-path
Draft

fix(preset-eleventy): write posts where the advertised URL resolves#916
rmdes wants to merge 1 commit into
mainfrom
fix/eleventy-post-url-matches-path

Conversation

@rmdes

@rmdes rmdes commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Fixes half of #902 — the Eleventy half, which is fully solvable inside the preset.

The problem

getPostTypes puts the date in the filename and advertises it as path segments:

path: `${collection}/{yyyy}-{MM}-{dd}-{slug}.md`,
url:  `${collection}/{yyyy}/{MM}/{dd}/{slug}`,

Eleventy derives a page's URL from its input path and makes no such translation, so the URL returned in the Location header — and shown in the interface as "Post will be created at …" — doesn't resolve. The file is written correctly and the request succeeds, so nothing surfaces the problem. If syndication is enabled, the dead URL has already gone out.

The change

One line: write the date as directories.

- path: `${collection}/{yyyy}-{MM}-{dd}-{slug}.md`,
+ path: `${collection}/{yyyy}/{MM}/{dd}/{slug}.md`,
   url: `${collection}/{yyyy}/{MM}/{dd}/{slug}`,

The url template is untouched, so the advertised URL scheme doesn't move — this only makes the file land where that URL already pointed.

Verification

Eleventy 3, stock config, dir.input = content:

content/notes/2026/08/22/hello.md  →  _site/notes/2026/08/22/hello/index.html

which is exactly notes/{yyyy}/{MM}/{dd}/{slug}.

Test suite: 10 pass, 0 fail. eslint and prettier --check clean on the changed files.

On the test

The three existing expectations asserted the old path, so they move with the change. I've also added one that asserts the property the issue is about, rather than the literal strings:

it("Advertises a post URL Eleventy serves from the same path", () => {
  for (const type of ["article", "note", "puppy"]) {
    const { path, url } = result.get(type).post;
    assert.equal(path, `${url}.md`, );
  }
});

Nothing currently tests that path and url agree, which is why this was invisible. On the unfixed code it fails with:

article: Eleventy derives a page's URL from its input path, so a post written to
`articles/{yyyy}-{MM}-{dd}-{slug}.md` is not served at `articles/{yyyy}/{MM}/{dd}/{slug}`
  actual:   'articles/{yyyy}-{MM}-{dd}-{slug}.md'
  expected: 'articles/{yyyy}/{MM}/{dd}/{slug}.md'

Worth knowing

  • Existing sites keep their current URLs — old files stay where they are and continue to be served from there. Only newly written posts use the dated directories, and those are the ones whose advertised URL now resolves.
  • Anyone who worked around this by configuring a permalink to match the flat filename would want to revisit that.
  • preset-jekyll needs a different fix (front-matter permalink) and is left for a separate PR; preset-hugo is unaffected.

`getPostTypes` put the date in the filename but advertised it as path
segments:

    path: `${collection}/{yyyy}-{MM}-{dd}-{slug}.md`
    url:  `${collection}/{yyyy}/{MM}/{dd}/{slug}`

Eleventy derives a page's URL from its input path and makes no such
translation, so the URL returned in the `Location` header and shown as
"Post will be created at …" does not resolve. The file is written
correctly and the request succeeds, so nothing surfaces it.

Write the date as directories instead, so the path Eleventy serves is
the URL Indiekit reported. The `url` template is unchanged, so the URL
scheme itself does not move.

Verified against Eleventy 3: `content/notes/2026/08/22/hello.md` builds
to `_site/notes/2026/08/22/hello/index.html`.

Refs #902
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant