@apostrophecms/redirect

中文文档
1.7.1发布于 2026/10/01MITCommonJS零依赖近 30 天下载 2323

Manage redirects for apostropheCMS

原始使用文档
文档目录19 节
  1. Installation
  2. Configuration
  3. statusCode
  4. withType
  5. skip
  6. caseInsensitive
  7. Usage
  8. Matching the query string
  9. Matching wildcards
  10. Exact matches always win
  11. Capturing wildcards
  12. Creating fallbacks with multiple wildcard rules
  13. Safety concerns
  14. Soft redirects: when you don't need this module at all
  15. Extending the module
  16. Providing a fallback handler
  17. Preempting the redirect module
  18. Executing the middleware sooner
  19. Redirecting to other locales
ApostropheCMS logo

Manage site redirects for ApostropheCMS

Installation

First make sure you have an Apostrophe project!

Then:

npm install @apostrophecms/redirect

Configuration

In app.js, add the module to your configuration:

require('apostrophe')({
  shortName: 'MYPROJECT',
  modules: {
    '@apostrophecms/redirect': {}
  }
});

statusCode

Defaults to 302 By passing statusCode to your configuration you can change the default status code value. Accepted values are 301 and 302

// Other modules, then...
'@apostrophecms/redirect': {
  options: {
    statusCode: 301
  }
}

Note that permanent redirects are cached by Google for a long time. It is a good idea to encourage users to test with a temporary redirect first, then switch to permanent which is an SEO best practice — as long as it's correct.

withType

Defaults to @apostrophecms/page By passing withType to your configuration you can specify the document type your internal redirects can redirect to.

// Other modules, then...
'@apostrophecms/redirect': {
  options: {
    withType: 'article'
  }
}

Note: Apostrophe 2 supported creating relationships to multiple doc types from a single interface. This feature doesn't yet exist in the newer versions of Apostrophe, as such redirects can only specify a single doc type to redirect to.

skip

For performance the redirect check can be skipped for URLs matching certain regular expressions. The default configuration of the skip option is:

// Other modules, then...
'@apostrophecms/redirect': {
  options: {
    skip: [ /\/api\/v1\/.*/ ]
  }
}

If you wish to skip other patterns, we recommend keeping the default one as it speeds up API calls.

caseInsensitive

Defaults to false

By passing caseInsensitive: true to your configuration, the "Old URL" of every redirect is matched against incoming request URLs without regard to case. This is useful when migrating from a case-insensitive web server (e.g. IIS), where redirect rules may have been entered with mixed-case slugs such as /Events or /About-Us/Partners, but inbound traffic (old bookmarks, search engine results, external links) may arrive with any casing, such as /events or /EVENTS.

// Other modules, then...
'@apostrophecms/redirect': {
  options: {
    caseInsensitive: true
  }
}

When this option is enabled:

  • New and edited redirects have their "Old URL" stored in lowercase automatically.
  • A migration runs to lowercase the "Old URL" of any existing redirects.
  • Incoming request URLs are lowercased before being matched against stored redirects (the original casing of the request is still used when substituting a wildcard match into a destination URL).

⚠️ This option does not support "mixing" case-sensitive and case-insensitive redirects. Enabling it lowercases all existing "Old URL" values, and this migration is not reversible. If you later disable caseInsensitive, your pre-existing redirects will only match lowercase request URLs, since their stored "Old URL" values remain lowercase. If this matters to you, you would need to manually recreate the affected redirects with their original mixed-case "Old URL" values.

Usage

While logged in as an admin, click the "Redirects" button. A list of redirects appears, initially empty. Add as many redirects as you like. The "from" URL must begin with a /. The "to" URL may be anything and need not be on your site. The "description" field is for your own convenience.

Matching the query string

By default a redirect includes any query string (the ? and whatever follows it, up to but not including any #) on incoming requests when matching for redirection.

You can toggle the "ignore query string when matching" option in a redirect definition to ignore query strings on incoming requests and only match on the base URL path. A redirect that does not use this option will always match first, so you can match various specific query strings and then have a fallback rule for other cases.

Matching wildcards

Normally, aside from the query string, only an exact match is honored. If you wish to redirect an entire subdirectory, you may use a * immediately after a /, for example:

/auto/*

This will redirect all URLs beginning with /auto/ to your destination, like this:

/auto/hyundai -> /fr/auto
/auto/hyundai/ioniq-5 -> /fr/auto

⚠️ Note that this discards the rest of the URL. If this is not what you want, see below for ways to avoid it.

Exact matches always win

If you have a redirect rule with no *, it will always beat a redirect rule with an *.

For instance, if you have rules like this:

/auto/gm/bolt -> /en/auto/gm/bolt
/auto/* -> /fr/auto

Then actual redirects will play out like this:

/auto/gm/bolt -> /en/auto/gm/bolt
/auto/toyota/tercel -> /fr/auto

Capturing wildcards

If you are creating a "URL" redirect, and not an "Internal Page" one, you may also "capture" and reuse the rest of the URL by including the * . This is useful when the rest of the URL is still correct.

For instance, if your "Old URL" is:

/auto/*

And you select "URL" as the redirect type and type the following in the "URL" field:

/fr/auto/*

Then redirects will occur like this:

/auto/hyundai -> /fr/auto/hyundai
/auto/hyundai/ioniq-5 -> /fr/auto/hyundai/ioniq-5

Creating fallbacks with multiple wildcard rules

Note that if you have two redirect rules involving an * and one is longer than the other, the longer match always wins.

For example, if your redirects are set up like this:

/auto/hyundai/* -> /en/car/hyundai/*
/auto/* -> /fr/auto/*

Then redirects will play out like this:

/auto/mercedes -> /fr/auto/mercedes
/auto/mercedes/w123 -> /fr/auto/mercedes/w123
/auto/hyundai -> /en/car/hyundai
/auto/hyundai/ioniq-5 -> /en/car/hyundai/ioniq-5

Safety concerns

Be aware that each redirect is live as soon as you save it and that it is possible to make a mess with redirects. A few obvious dangers like redirecting /* or /api/v1/* are locked out, but it is still possible to cause problems depending on your site's structure. In a pinch, you can remove unwanted redirects via the MongoDB command line client (look for { type: "@apostrophecms/redirect" } in the aposDocs collection in MongoDB).

Soft redirects: when you don't need this module at all

For your convenience, ApostropheCMS automatically creates "soft redirects" every time you change the slug of a page or piece, provided the document was accessed at least once at the old URL. So you shouldn't need to manually create a "hard redirect" in that situation.

Extending the module

Providing a fallback handler

If you wish to handle redirects in another way when this module does not find a match, you can do so by listening for the @apostrophecms/redirect:noMatch event. This event handler receives req, result. To issue a redirect, set result.redirect in your event handler. To issue a "raw" redirect to which any sitewide prefix is not appended automatically, set result.rawRedirect in your event handler. You can also set result.status to match your need as the status code of the redirection, default is 302.
If you wish to alter the target url when a redirection is about to come, like for example to change the domain, you can listen to the @apostrophecms/redirect:beforeRedirect. This event handler receives req, result. result will have two properties that you can alter before the redirection: status and url. Do not call req.res.redirect() yourself in your event handler in those two cases.

For example:

// modules/redirect-fallback/index.js
module.exports = {
  handlers(self) {
    return {
      '@apostrophecms/redirect:noMatch': {
        // will be awaited, you can do queries here if needed
        async fallback(req, result) {
          if (req.url.match(/pattern/)) {
            result.redirect = '/destination';
          }
        }
      }
    }
  }
}

Preempting the redirect module

If your goal is to preempt this module by making a decision to redirect differently in some cases before this module looks for a match, register your own middleware and perform the redirect there. Use before to specify that your own module's middleware comes first.

For example:

// modules/early-redirect/index.js
module.exports = {
  middleware(self) {
    return {
      earlyRedirect: {
        before: '@apostrophecms/redirect',
        middleware(req, res, next) {
          if (req.url.match(/pattern/)) {
            return res.redirect('/destination');
          } else {
            return next();
          }
        }
      }
    };
  }
};

Executing the middleware sooner

By default the middleware of this module that checks for redirect is executed depending on the place of this module in your modules configuration.
You can choose to execute it before any other module by setting the before option, indicating before which module middleware this one should run (for example @apostrophecms/global).
Note that by doing this, the above preemption will not work anymore.

Redirecting to other locales

It's possible to redirect from one locale to another one, with external redirections, since you manually define the url to redirect to.

As for internal redirects (relationships with pages), this works across locales as well, but keep in mind that you will only see the internal redirects that target the current locale when managing redirects. To find redirects that target an internal page in a different locale, switch locales before viewing "Manage Redirects."

A note for developers: a query builder called currentLocaleTarget hides redirects that have relationships to other locales (different from the current one). If you want to get all redirects whatever the locale of their internal redirects you can undo this behavior using the query builder:

const redirects = await self.apos.modules['@apostrophecms/redirect']
    .find(req)
    .currentLocaleTarget(false)
    .toArray();

版本与发布记录

@apostrophecms/redirect 共发布 18 个版本,首次发布于 2021/06/25;过去 12 个月发布了 5 个版本。

版本发布日期距今
1.7.1latest2026/10/011 个月前
1.7.02026/07/113 个月前
1.6.02026/06/114 个月前
1.6.0-alpha.1alpha2026/06/055 个月前
1.5.02025/11/2611 个月前
1.5.0-beta.1beta2025/11/051 年前

关于 @apostrophecms/redirect 的常见问题

@apostrophecms/redirect 是什么?

Manage redirects for apostropheCMS

如何安装 @apostrophecms/redirect?

在项目目录运行 npm install @apostrophecms/redirect,或使用 pnpm add / yarn add / bun add。

@apostrophecms/redirect 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/apostrophecms__redirect 是否存在。

@apostrophecms/redirect 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@apostrophecms/redirect 可以商用吗?

@apostrophecms/redirect 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@apostrophecms/redirect 的下载量有多少?

根据 npm 官方下载统计,@apostrophecms/redirect 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,323 次,日均约 77 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@apostrophecms/redirect 还在维护吗?

最新版本 1.7.1 发布于 2026/10/01(1 个月前);至今共发布 18 个版本,其中过去 12 个月发布了 5 个;首次发布于 2021/06/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。