URLs and redirects

On this page

From paths

A file's URL is its path in content/ without .md, as a folder: content/blog/hello.md is written to dist/blog/hello/index.html and served at /blog/hello/. An index.md is the page of its folder. URLs that differ only in case are an error, because many hosts cannot tell them apart.

The frontmatter can change the last segment with slug, or the whole URL with permalink:

---
title: About us
slug: about
---

A collection's permalink builds its URLs from variables:

blog: { permalink: "/blog/:year/:month/:slug/" },
VariableValue
:slugThe file name, or the frontmatter slug.
:year, :month, :dayFrom the date field, in the config's timezone.
:pathThe file's subfolder in the collection; disappears when there is none.

A frontmatter permalink still wins over the pattern.

Trailing slashes

By default every page is a folder with an index.html and URLs end in /. With trailingSlash: false in the config, pages are written as hello.html and linked as /blog/hello. kilim preview serves both the way static hosts do.

Redirects

When a page moves, keep its old URL working with aliases in its frontmatter:

---
title: Hello world
aliases: ["/2026/hello/"]
---

Or list redirects in redirects.txt at the site root, one per line:

/old-page/ /new-page/
/docs/setup/ /getting-started/installation/

Kilim writes a small page at each old URL that sends visitors and search engines on (a meta refresh with a canonical link), and a _redirects file for hosts that read it, such as Cloudflare Pages. kilim check reports redirects that lead to another redirect, and links to redirected URLs. In kilim dev, renaming a page in the admin can add the old URL to aliases for you.

The 404 page

content/404.md becomes /404.html, the page static hosts show for a missing URL. It is noindex and stays out of the sitemap, feeds and lists.