Redirect a moved page with a hash file

Best practice By design
When a page moves for good, keep the old URL alive with a file named after the old path plus .old - for /tjenester/Salgsportaler that is tjenester/Salgsportaler.old - containing only the new URL. Docly answers it with 301 Moved Permanently. docly.redirect("/new-url") in a hash file answers 302 (temporary) since 15 October 2026 - use it for temporary or conditional redirects, not for a permanent move. Call docly.redirect with one argument only - docly.redirect(url, 301) does not redirect. A document with the built-in schema Internet Shortcut (a .url file) also answers 301, to the URL it holds.
Applies to: Hash templates

What you'll see

A page is moved, renamed or merged into another page – a service page moves into a new topic folder, two competing pages are consolidated, or a document is replaced by a hub. The old URL is linked from other sites, bookmarked and indexed by search engines, so it must keep working and pass its ranking on to the new address.

Docly has no redirect table in the site configuration, so the redirect has to live at the old path itself.

What's actually happening

Two ways to redirect, with different status codes.

  • A .old file at the old path answers HTTP 301 Moved Permanently. When nothing else exists at the requested path, Docly looks for <path>.old and redirects to the URL written in it (a relative target such as /portaler is expanded to an absolute URL). A 301 is what search engines expect for a permanent move: they transfer the old URL's signals to the target and replace it in the index.
  • docly.redirect(url) in a hash file answers HTTP 302 Found — a temporary redirect — since 15 October 2026. Before that it answered 301 by mistake. Use it when the redirect depends on something (a condition, a parameter) or is not permanent.

A third form needs no code either: a document with the built-in schema Internet Shortcut — a .url file whose content is [InternetShortcut] followed by a line URL=https://… — answers 301 to that URL when it is requested. Use it for a link that should leave the site, such as a short address for a booking system.

Neither is frozen by the hash cache (see Hash files are cached): changing the target takes effect on the next request.

docly.redirect takes one argument. #docly.redirect("/portaler", 301)# returns 200 with an empty body and no Location header — the visitor gets a blank page and search engines see a live, empty page. You cannot choose the status code with it; use a .old file for a 301.

What to do

Do – a permanent move: a .old file at the old path whose whole content is the new URL:

tjenester/Salgsportaler.old   →   /portaler/salgsportal

The .old file is only consulted when nothing else exists at the old path, so the old page itself must be gone.

Do – a temporary or conditional redirect: one line, one argument, in a hash file at the old path:

#docly.redirect("/portaler/salgsportal")#   <!-- 302 -->

Don't – a second argument:

#docly.redirect("/portaler/salgsportal", 301)#   <!-- 200, blank page, no redirect -->

Checklist when moving a page:

  • If the old URL was served by a document (Salgsportaler.docly), take a copy with docly get --raw and delete it before creating the redirect — a document at the path wins, and a .old file is never consulted while it exists.
  • Folder listings built with docly.getFiles() also return a redirect file. Filter on fileschema (see getFiles returns every file in the folder), or the redirect shows up as an empty card or menu item.
  • Remove the old URL from the sitemap and add the new one. A sitemap must not list URLs that redirect.
  • Update internal links to point straight at the new URL. The redirect is for the outside world; internal links through a redirect cost an extra round trip.
  • Verify with curl -I https://your-domain/old-url: expect 301 for a .old file or a .url shortcut, 302 for docly.redirect, and the right Location.

To move a page into a folder of the same name (a file kunstig-intelligens.hash becoming the folder kunstig-intelligens/), no redirect file is needed — see A folder takes precedence over a file with the same name.