Skip to content
Cloudflare Docs

Redirects

As your content changes (and it will change), redirects preserve continuity for your users and (friendly) bots.

The most obvious part of this is the user experience. If you click a link in the dashboard or use a bookmarked URL, you trust that it's taking you to the right place. Not a 404 page or the wrong page, but the right page. Redirects help direct users to the right place.

The same applies to the automated experience. If you move a page without redirects, you are losing the historical search authority that Google and other search engines use to rank your page.


How we add redirects

Cloudflare Workers (primary)

Our primary method takes advantage of Workers Static Assets, defining redirects in a plain text file in our GitHub repo.

This setup allows us to use the same workflow for redirects as for any other documentation change. We implement a redirect in the same pull request as the content change and can test these changes in our preview branches. For maintenance, we try to keep these redirects organized by product and then — within each product — organized alphabetically.

We also love the flexibility provided by the Pages syntax.

Bulk redirects (secondary)

In certain situations, we also use Bulk redirects. We use this strategy sparing because having redirects in multiple places increases the cognitive load and potential confusion of making a change.

Normally, bulk redirects only come up when another team is adding a large number of individual redirects to our site, such as when all of our previous support.cloudflare.com content was migrated and needed individualized redirects per locale.

We use this method when the contributors are outside of our team and when the total number of redirects is so large that it would clutter our __redirects file and count against our limit for redirects.


When we add redirects

Our team adds redirects in two situations: during the course of normal content and as needed based on data.

During content work

During normal content work, you want to add redirects when you do the following to a page:

  • Change any part of the URL (filename, folder).
  • Delete the page.

We have some automation to help flag needed redirects.

Based on data

Another time to add redirects is when you see a lot of 404 response codes on certain paths of your docs site. These 404 responses might be due to a missing redirect or mistyped link.

We identify these status codes either through our Cloudflare analytics (ad hoc) or Logpush job (more thorough, quarterly).


How we automate redirects

We have two automations in GitHub to help with redirects.

Infinite redirects

An infinite redirect is when two pages keep redirecting to each other, trapping users in an infitnite loop that will crash their browser.

Because that's just a terrible experience, we explicitly check for that as part of our required CI GitHub action.

We trigger this check after we build our site. What it does it then call validate-redirects.ts, which fails on:

  • Infinite redirects
  • Duplicate redirects
  • Redirect targets with anchor links in them

validate-redirects.ts

validate-redirects.ts
import { readFile } from "fs/promises";
async function main() {
const redirects = await readFile("public/__redirects", { encoding: "utf-8" });
let numInfiniteRedirects = 0;
let numUrlsWithFragment = 0;
let numDuplicateRedirects = 0;
const redirectSourceUrls: string[] = [];
for (const line of redirects.split("\n")) {
if (line.startsWith("#") || line.trim() === "") continue;
const [from, to] = line.split(" ");
if (from === to) {
console.log(`✘ Found infinite redirect:\n ${from} -> ${to}`);
numInfiniteRedirects++;
}
if (from.includes("#")) {
console.log(`✘ Found source URL with fragment:\n ${from}`);
numUrlsWithFragment++;
}
if (redirectSourceUrls.includes(from)) {
console.log(`✘ Found repeated source URL:\n ${from}`);
numDuplicateRedirects++;
} else {
redirectSourceUrls.push(from);
}
}
if (numInfiniteRedirects || numUrlsWithFragment || numDuplicateRedirects) {
console.log("\nDetected errors:");
if (numInfiniteRedirects > 0) {
console.log(`- ${numInfiniteRedirects} infinite redirect(s)`);
}
if (numUrlsWithFragment > 0) {
console.log(`- ${numUrlsWithFragment} source URL(s) with a fragment`);
}
if (numDuplicateRedirects > 0) {
console.log(`- ${numDuplicateRedirects} repeated source URL(s)`);
}
console.log("\nPlease fix the errors above before merging :)");
process.exit(1);
} else {
console.log("\nDone!");
}
}
main();

Potential redirects

Contributors often struggle to know when they should add redirects. We try to help them by adding a comment to any pull requests that modify or delete content file paths.

GitHub Actions redirect comment

Other guidance

Organize your redirects

As much as you can, try to organize your redirects into logical groups (products, alphabetical order). This process helps prevent duplicate redirects, as well as identifying specific ones you might be looking for.

In our __redirects file, we use extensive comments, separating different product areas. We also try, as much as we can, to keep the redirects in alphabetical order within a section.

We used to apply a similar principle to Bulk Redirect lists (when that was our primary method). We created lists that grouped together similar products and labeled them as such, so it was easier to find which redirect you were looking for.

Know what you can redirect

At the server level, you can trigger a redirect on a URL path (/page/), but not a fragment (/page/#fragment).

You can redirect a page to a fragment, however (/page1/ to /page2/#fragment).

Avoid redirect chains

If possible, have all redirects send your users directly to their destination instead of chaining together redirects.

Otherwise, you can have the following situation:

Page 1 --Redirect-> Page 2 --Redirect-> Page 3 --Redirect-> Page 4

Redirect chains are bad because they:

  • Slow down the user experience.
  • Increase the likelihood of unintentional outcomes (infinite redirects, missing redirects, incorrect redirects).

A way to avoid this outcome is by continually updating the destinations of previous redirects. For example, let's say you changed the name of this page to /style-guide/how-we-docs/redirect-guidance/.

In the pull request to update your redirects file, you would want to update the existing redirect as well as adding a new redirect:

__redirects
/style-guide/redirects/ /style-guide/how-we-docs/redirects/ 301
/style-guide/redirects/ /style-guide/how-we-docs/redirect-guidance/ 301
/style-guide/how-we-docs/redirects/ /style-guide/how-we-docs/redirect-guidance/ 301