# jekyll-redirect-from: giving a Jekyll page more than one URL

> This Jekyll plugin lets a post or page declare a list of old URLs that should point at it, and it implements them by generating static HTML files with an HTTP-REFRESH meta tag, so nothing has to be configured on the web server. The interesting details are in the trailing slash rules, the prefix handling and the escaping guarantees for a custom layout.

**jekyll/jekyll-redirect-from** — :twisted_rightwards_arrows: Seamlessly specify multiple redirections URLs for your pages and posts.

- Repository: https://github.com/jekyll/jekyll-redirect-from
- Stars: 812 · Forks: 127
- Language: Ruby
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/jekyll-jekyll-redirect-from

## Redirects as generated HTML, not server rules

JekyllRedirectFrom gives Jekyll posts and pages multiple URLs, and the mechanism is deliberately simple. Redirects are performed by serving an HTML file with an HTTP-REFRESH meta tag pointing at the destination. The README is explicit about what does not happen: no .htaccess file, no nginx configuration, no XML file, and nothing else is generated. The plugin simply creates HTML files.

That constraint is the plugin's main appeal. A static site generator has no access to the web server, so a redirect expressed as server configuration is a redirect you cannot express at all. Emitting a file for each old path means the redirect works on any host, including GitHub Pages, where the server configuration is not yours.

The problem it addresses is concrete. The README describes importing posts and pages from somewhere like Tumblr, where it is annoying and impractical to create a new page in the proper subdirectory for every old URL so that it redirects to the new post. Instead of maintaining those pages by hand, you declare them in front matter and the plugin generates them.

The project is MIT licensed, written in Ruby, and the most recent release is v0.17.0 from 2026-09-30. The last push was on 2026-10-03, so the plugin is currently maintained.

## Installing the plugin in a Jekyll site

The plugin is a Ruby gem and installs the way Jekyll plugins do. The Gemfile gains one line:

```ruby
gem 'jekyll-redirect-from'
```

After that you install the bundle, or you install the gem yourself:

```bash
$ bundle
```

```bash
$ gem install jekyll-redirect-from
```

The plugin then has to be enabled in the site configuration:

```yaml
plugins:
  - jekyll-redirect-from
```

Two compatibility notes come with that. On a Jekyll version older than 3.5.0 the entry belongs under the gems key rather than plugins, because the plugins key did not exist before then. And if you build in safe mode, the way of mimicking GitHub Pages, the plugin has to be added to the whitelist, otherwise the safe-mode build refuses to load it:

```yaml
whitelist:
  - jekyll-redirect-from
```

With that in place you run the usual jekyll command with the safe flag, exactly as you would without the plugin.

## Declaring the old URLs in front matter

The whole interface is one front-matter key. You add a redirect_from array to a page or post and list the URLs that should point at it:

```yaml
title: My amazing post
redirect_from:
  - /post/123456789/
  - /post/123456789/my-amazing-post/
```

A single URL can be given as a plain string instead of an array, which is the shorthand for the common case of one old address:

```yaml
title: My other awesome post
redirect_from: /post/123456798/
```

The trailing slash decides the shape of the file that gets written, and this is the part that catches people out. A redirect with a trailing slash generates a corresponding subdirectory containing an index.html. A redirect without a trailing slash generates a corresponding filename with no extension and no subdirectory. So an entry of /post/123456789/my-amazing-post produces a file at that path, while the same entry with a slash produces /post/123456789/my-amazing-post/index.html.

Each of those generated files contains the HTTP-REFRESH meta tag that sends the visitor to the destination URL. The practical consequence is that you should write the old URL exactly as it was, because the difference between a directory and a file is the difference between a URL that resolves and one that 404s.

## How the prefix is worked out

A redirect has to point at an absolute address, and the plugin derives that prefix from the site configuration rather than making you write it in every entry.

If site.url is set, its value together with site.baseurl is used as the prefix for the redirect URL automatically. If site.url is not set, only site.baseurl is used, if that is set as well. The README describes the scenario this exists for: a site that is not available from the domain root, where the redirects would otherwise point at the wrong path.

GitHub Pages gets its own rule. The README notes that if you host on GitHub Pages and site.url is not set, the prefix is set to the pages domain name, for example http://example.github.io/project, or to your custom CNAME. So on a project site with the url unset, the plugin infers the right prefix rather than producing redirects to a domain that does not exist.

This is worth understanding rather than assuming, because the failure is quiet. A wrong prefix produces redirects that resolve and then lead somewhere useless, and the site itself keeps working fine.

## Sending a page to a different site, and the limits

Sometimes a page should not point at another page of yours but at a different website entirely, and the redirect_to key covers that case:

```yaml
title: My amazing post
redirect_to: http://www.github.com
```

The value has to be a relative path or an http:// or https:// URL. Other schemes are ignored, and the plugin logs a warning, which is a sensible guard against a javascript: URL turning a redirect page into a script execution vector.

There is a second limit that applies to both keys. The README states that using redirect_to or redirect_from with collections will only work with files which are output to HTML, such as .md, .textile and .html. A collection whose documents are written in another format produces output the plugin cannot attach a redirect page to, so the front-matter key is silently irrelevant there.

That constraint is easy to meet in practice, since most Jekyll collections are Markdown, but it is worth checking if your collection uses a custom output format.

## Customising the redirect layout and the escaping rules

The generated page is a real page, so you can replace it. If you want your own template, you create a layout called redirect.html in the site's _layouts directory, and the plugin uses it instead of its default.

The layout receives three variables. page.redirect.from is the relative path to the redirect page. page.redirect.to is the absolute URL to the target page, where one is available. page.redirect.to_js is that same value as a quoted JavaScript string literal, safe to use inside a script element.

The escaping behaviour is the part with real substance. Characters that could break out of HTML or JavaScript, which the README lists as quotes, angle brackets, backslashes, backticks, curly braces, whitespace and control characters, are percent-encoded in page.redirect.to. So a custom layout that outputs the value without escaping is still safe from injection.

That is a safety net rather than a licence to skip escaping. The README still recommends using the escape filter in HTML attributes and using page.redirect.to_js inside scripts, and the reason is practical: percent-encoding a URL changes it, so if you want the raw address in an href attribute, the escape filter gives you the correct markup, and for scripts the dedicated JavaScript literal form is the one that cannot terminate the script element early.

## redirects.json and the option to drop it

By default a file called redirects.json is included in the build output. The README describes two uses for it: automated testing, and implementing server-side redirects.

The second use is the important one, because it addresses the limitation of the generated HTML approach. A meta refresh in an HTML file is a client-side redirect, and a server that can read a manifest can issue a proper HTTP redirect instead, which behaves differently for crawlers, for clients that do not run scripts and for anything measuring a hop. The plugin does not do that itself; it provides the data that lets your host or an edge layer do it.

If you do not want the file in your output, the configuration key turns it off:

```yml
redirect_from:
  json: false
```

The key sits under the redirect_from configuration entry in _config.yml, which is otherwise empty of options, so the plugin's whole configuration surface is this single boolean.

## Maintenance, repository layout and licence

The repository is a conventional Ruby gem, with a gemspec, a Rakefile, a spec directory and an .rspec file, plus a rubocop configuration with a companion todo file for existing offences. A History.markdown file holds the change history, and the script directory holds the release helpers.

The release history explains the pace. There was v0.15.0 in March 2019, v0.16.0 in January 2020, and then nothing until v0.17.0 at the end of September 2026. Six years between the second and third release says this is a stable plugin that changes rarely, and the fact that the new release came out at all, after a decade of stability, is the more useful signal than the version number itself.

The licence is MIT, with a LICENSE.txt file at the root of the repository. MIT is permissive, with no copyleft obligations and no requirement to publish changes, so a site can use the plugin in a commercial or closed project without conditions. That is a description of the terms rather than legal advice.

The contribution section is the conventional five steps: fork the repository, create a feature branch, commit the changes, push the branch and open a pull request.

## Conclusion

Adopt jekyll-redirect-from when you have migrated content from another platform and old URLs must keep resolving, especially on GitHub Pages where you cannot configure the server. Do not adopt it when you need true HTTP status redirects, because the generated files are HTML pages with a meta refresh rather than server responses, and consult redirects.json or your own edge rules for that. Verify first that the plugin is listed in your _config.yml plugins array, that it is whitelisted if you build in safe mode, and that the trailing slash you write in each redirect_from entry matches the URL shape you are trying to preserve.

## FAQ

### How do I redirect a Jekyll page from an old URL?

Add a redirect_from array to the front matter of the page or post listing the old paths. Each generated file contains an HTTP-REFRESH meta tag pointing at the new URL, and no server configuration is involved.

### What is the difference between a redirect_from entry with and without a trailing slash?

An entry with a trailing slash generates a subdirectory containing an index.html, while an entry without one generates a file with no extension and no subdirectory. Write each old URL exactly as it was so the generated path matches.

### How do I use jekyll-redirect-from with a safe mode build?

Add jekyll-redirect-from to the whitelist in _config.yml alongside listing it under plugins, because a safe mode build refuses to load plugins that are not whitelisted. On Jekyll older than 3.5.0 the entry belongs under the gems key instead of plugins.

### Can jekyll-redirect-from redirect to a different website?

Yes, with the redirect_to key, where the value must be a relative path or an http:// or https:// URL. Other schemes such as javascript: are ignored and a warning is logged.

## Sources

- [Issues](https://github.com/jekyll/jekyll-redirect-from/issues)
- [jekyll/jekyll-redirect-from on GitHub](https://github.com/jekyll/jekyll-redirect-from)
- [License: MIT](https://github.com/jekyll/jekyll-redirect-from/blob/master/LICENSE)
- [README](https://github.com/jekyll/jekyll-redirect-from/blob/master/README.md)
- [Releases](https://github.com/jekyll/jekyll-redirect-from/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jekyll-jekyll-redirect-from
