This plugins enables you to create HTTP redirections in your Metalsmith website. There are several ways to do so:
- in the plugin configuration (see
options.redirections
) - in your source frontmatters via the
redirectFrom
andredirectTo
keys (seeoptions.frontmatter
)
npm install metalsmith-redirect
metalsmith.json
{
"plugins": {
"metalsmith-redirect": {
"redirections": {
"/about": "/about-me",
"/images": "/search?kind=image"
}
}
}
}
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
redirections: {
'/about': '/about-me',
'/images': '/search?kind=image',
},
})
)
Notes:
- Due to restrictions in the client-side implementation, the source
must either be an HTML file, or a folder (in which case
'/index.html'
will be appended) - The destination can be any kind of path
- A relative path in the source will be resolved based on the site root
'/'
- A relative path in the destination will be resolved based on the source directory
- It is best to place this plugin in the latest position, so that the paths it is dealing with have already been altered by the other plugins
Type: Object
Default: {}
Type: Object
Default: {}
Each key value pair from the object will be used to create a redirection, where each key corresponds to the source url and its associated value to the destination url.
Example
In this piece of code we create two redirections:
- from
/about
to/about-me
- from
/images
to/search?kind=image
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
redirections: {
'/about': '/about-me',
'/images': '/search?kind=image',
},
})
)
Type: boolean | Object
Default: false
By setting this options to true
, this plugin will gather redirections from
frontmatters. This feature is convenient to keep the redirections close to
the code. You can also pass an object instead, see below for the nested options.
Example: redirect from another page
Let's consider you have a file /photos/index.html
, if you want to create a
redirection from /images
, you would update its frontmatter in this
fashion:
/photos/index.html
---
redirectFrom: /images
---
Example: redirect from several pages
It is also possible to create redirections from several pages by passing a
list to redirectFrom
:
/photos/index.html
---
redirectFrom:
- /images
- /pictures
---
Example: redirect to another page
Let's consider you have a file /about.md
, if you want to create a
redirection to /about-me
, you would update its frontmatter in this fashion:
/about.md
---
redirectTo: /about-me
---
Type: string
Default: "redirectFrom"
The redirectFrom path to search for in the frontmatters. It leverages
_.get
, so you can perform queries like:
config.redirectFrom
or envs[0].redirectFrom
.
Example
Let's say I like to keep things tidied up and I want to scope all my plugin
configuration under the config
key, this is how it is possible to instruct
the plugin to do so:
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
frontmatter: {
redirectFrom: 'config.redirectFrom',
},
})
)
The plugin will then look for the config.redirectFrom
key in any of the
frontmatters, like this one:
---
config:
redirectFrom: /about
---
Type: string
Default: "redirectTo"
The redirectTo path to search for in the frontmatters. It leverages
_.get
, so you can perform queries like:
config.redirectTo
or envs[0].redirectTo
.
Example
Let's say I like to keep things tidied up and I want to scope all my plugin
configuration under the config
key, this is how it is possible to instruct the plugin to do so:
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
frontmatter: {
redirectTo: 'config.redirectTo',
},
})
)
The plugin will then look for the config.redirectTo
key in any of the
frontmatters, like this one:
---
config:
redirectTo: /about-me
---
Type: boolean | Object
Default: false
This option allows to preserve the hash while navigating from the source to the destination url.
For example if you redirect /a
to /b
, a visitor currently at
/a#comments
will be redirected to /b#comments
.
Note: this feature will optimistically try to leverage JavaScript to redirect the user, as this is the only way to access the location hash. This will work in most cases, but for some users with JavaScript disabled this means they could remain stuck. When this happens it should fallback to the html meta redirection (which cannot preserve the hashes due to its static nature).
Example
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
preserveHash: true,
})
)
Type: number
Default: 1
The number of second(s) after which the fallback should redirect the user when hash preservation is enabled.
Example
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
preserveHash: { timeout: 2 },
})
)
Type: string[]
Default: [".html"]
A list of all file extensions that should be considered HTML files. When files do not end in one of these extensions, it will not be allowed to be used as a redirection source.
Example
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('metalsmith-redirect')
metalsmith(__dirname).use(
metalsmithRedirect({
htmlExtensions: [".htm", ".html"],
})
)
Let's consider the following configuration:
{
"plugins": {
"metalsmith-redirect": {
"redirections": {
"foo": "hidden.html",
"/foo/bar.html": "/baz",
"/github": "https://github.com/segmentio"
}
}
}
}
The following redirections would be created:
source | destination |
---|---|
/foo/index.html |
/foo/hidden.html |
/foo/bar.html |
/baz |
/github/index.html |
https://github.com/segmentio |
Is this plugin compatible with metalsmith-broken-link-checker?
metalsmith-broken-link-checker will try to find dead links in your build.
If you .use()
it before you create the redirections, some dead links may be
detected as the redirections have not been created by metalsmith-redirect
yet. But if you .use()
it after metalsmith-redirect, it will be able to
consider the redirections, thus avoiding false positives. You can have a look
at these functional
tests
to see how the order in which the plugins are registered matters.