npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@fidian/metalsmith-redirect

v3.6.0

Published

A Metalsmith plugin to create HTTP redirections

Downloads

111

Readme

metalsmith-redirect

travis github npm

This plugins enables you to create HTTP redirections in your Metalsmith website. There are several ways to do so:

Install

npm install @fidian/metalsmith-redirect

Usage

CLI

metalsmith.json

{
  "plugins": {
    "@fidian/metalsmith-redirect": {
      "redirections": {
        "/about": "/about-me",
        "/images": "/search?kind=image"
      }
    }
  }
}

Node.js

const metalsmith = require('metalsmith')
const metalsmithRedirect = require('@fidian/metalsmith-redirect')

metalsmith(__dirname).use(
  metalsmithRedirect({
    redirections: {
      '/about': '/about-me',
      '/images': '/search?kind=image',
    },
  })
)

API

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

metalsmithRedirect(options)

options

Type: Object Default: {}

options.redirections

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.

In this piece of code we create two redirections:

  1. from /about to /about-me
  2. from /images to /search?kind=image
const metalsmith = require('metalsmith')
const metalsmithRedirect = require('@fidian/metalsmith-redirect')

metalsmith(__dirname).use(
  metalsmithRedirect({
    redirections: {
      '/about': '/about-me',
      '/images': '/search?kind=image',
    },
  })
)

options.frontmatter

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.

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
---

It is also possible to create redirections from several pages by passing a list to redirectFrom:

/photos/index.html

---
redirectFrom:
  - /images
  - /pictures
---

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
---

options.frontmatter.redirectFrom

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.

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('@fidian/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
---

options.frontmatter.redirectTo

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.

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('@fidian/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
---

options.preserveHash

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).

const metalsmith = require('metalsmith')
const metalsmithRedirect = require('@fidian/metalsmith-redirect')

metalsmith(__dirname).use(
  metalsmithRedirect({
    preserveHash: true,
  })
)

options.preserveHash.timeout

Type: number Default: 1

The number of second(s) after which the fallback should redirect the user when hash preservation is enabled.

const metalsmith = require('metalsmith')
const metalsmithRedirect = require('@fidian/metalsmith-redirect')

metalsmith(__dirname).use(
  metalsmithRedirect({
    preserveHash: { timeout: 2 },
  })
)

options.htmlExtensions

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.

const metalsmith = require('metalsmith')
const metalsmithRedirect = require('@fidian/metalsmith-redirect')

metalsmith(__dirname).use(
  metalsmithRedirect({
    htmlExtensions: [".htm", ".html"],
  })
)

FAQ

Can you give some example of the redirection algorithm?

Let's consider the following configuration:

{
  "plugins": {
    "@fidian/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.