|
| 1 | +--- |
| 2 | +title: Redirects and custom 404s |
| 3 | +description: What the _redirect file is and how to use them with a website or single-page application (SPA) on IPFS. |
| 4 | +--- |
| 5 | +# Redirects, custom 404s, and SPA support |
| 6 | + |
| 7 | +::: callout |
| 8 | +This feature is new, and requires Kubo 0.16 or later. |
| 9 | +::: |
| 10 | + |
| 11 | +This feature enables support for redirects, [single-page applications](#catch-all-and-pwa-spa-support), [custom 404 pages](#add-a-custom-404-page-to-your-website), and moving to IPFS-backed hosting [without breaking existing links](https://www.w3.org/Provider/Style/URI). |
| 12 | + |
| 13 | +## Evaluation |
| 14 | + |
| 15 | +This feature is limited to websites hosted in web contexts with unique [Origins](https://en.wikipedia.org/wiki/Same-origin_policy) for content roots, e.g., [subdomain](/how-to/address-ipfs-on-web/#subdomain-gateway) or [DNSLink](/how-to/address-ipfs-on-web/#dnslink-gateway) gateways. |
| 16 | + |
| 17 | +Redirect logic will only be evaluated if the requested path is not in the [DAG](/concepts/glossary/#dag). Any performance impact associated with checking for the existence of a `_redirects` file or evaluating redirect rules will only be incurred for non-existent paths. If there are any errors reading or parsing the `_redirects` file, the error codes will be returned with an HTTP 500 status code. |
| 18 | + |
| 19 | +## How to set up |
| 20 | + |
| 21 | +To define rules that will be executed when the requested path is not found in the DAG, there must be a file named `_redirects` stored underneath the root CID of the website. This `_redirects` file must be a text file containing one or more lines that follow the format explained below. |
| 22 | + |
| 23 | +### Format of the `_redirects` file |
| 24 | + |
| 25 | +Each line contained within the `_redirects` file has 3 basic components: |
| 26 | + |
| 27 | +```plaintext |
| 28 | +from to [status] |
| 29 | +``` |
| 30 | + |
| 31 | +1. The `from` path. This specifies the path to be redirected from. |
| 32 | +1. The `to` path. This specifies the path to be redirected to. |
| 33 | +1. The `status` component. This part is optional and specifies the HTTP status code that will be returned. (301, 404, etc.) |
| 34 | + |
| 35 | +For example, if you removed `home.html` and want to temporarily redirect traffic from `home.html` to `index.html`, the `_redirects` file should contain a line that looks something like this: |
| 36 | + |
| 37 | +```plaintext |
| 38 | +/home.html /index.html 302 |
| 39 | +``` |
| 40 | + |
| 41 | +### Status codes |
| 42 | + |
| 43 | +- `200` - OK (redirect will be treated as a rewrite, returning payload from alternative content path without changing the URL shown in the browser). |
| 44 | +- `301` - Permanent redirect (the default status). |
| 45 | +- `302` - Found (commonly used for temporary redirects). |
| 46 | +- `404` - Not found (defines custom 404 page). |
| 47 | +- `410` - Gone (the requested content has been permanently removed). |
| 48 | +- `451` - Unavailable for legal reasons. |
| 49 | + |
| 50 | +### Placeholders |
| 51 | + |
| 52 | +Placeholders are named variables that can be used to match path segments in the `from` path and inject them into the `to` path. |
| 53 | + |
| 54 | +This is useful for redirecting users to their desired content, even if the way your website is organized changed. |
| 55 | + |
| 56 | +For example, if I wanted to search for an article titled "hello world" that was written on June 15, 2022, I could search for it like this: `/posts/06/15/2022/hello-world` and be redirected to `/articles/2022/06/15/hello-world` |
| 57 | + |
| 58 | +```plaintext |
| 59 | +/posts/:month/:day/:year/:title /articles/:year/:month/:day/:title 301 |
| 60 | +``` |
| 61 | + |
| 62 | +There is also a special catch-all placeholder named `:splat` which represents everything captured via `*`. |
| 63 | + |
| 64 | +```plaintext |
| 65 | +/blog/* /new-blog/:splat 302 |
| 66 | +``` |
| 67 | + |
| 68 | +### Compatibility |
| 69 | + |
| 70 | +IPFS hosting supports only a subset of pre-existing standards supported by [Cloudflare](https://developers.cloudflare.com/pages/platform/redirects) and [Netlify](https://docs.netlify.com/routing/redirects/). |
| 71 | +There is no overwrite/shadowing: the file is evaluated only when requested path is not found in a [DAG](/concepts/glossary/#dag). |
| 72 | + |
| 73 | +::: tip |
| 74 | +For more detailed information about supported features, check out the [`_redirects` file specification](https://github.com/ipfs/specs/blob/main/http-gateways/REDIRECTS_FILE.md). |
| 75 | +::: |
| 76 | + |
| 77 | +## Examples |
| 78 | + |
| 79 | +### Catch all and PWA/SPA support |
| 80 | + |
| 81 | +The `200` status will be treated as a rewrite, returning OK without changing the URL shown in the browser. This staus code can be used to build [Progressive Web Apps](https://en.wikipedia.org/wiki/Progressive_web_app) and [Single Page Applications](https://en.wikipedia.org/wiki/Single-page_application). |
| 82 | + |
| 83 | +```plaintext |
| 84 | +/app/* /app/index.html 200 |
| 85 | +``` |
| 86 | + |
| 87 | +Opening `/app/this-does-not-exist` will return HTTP 200 response with content from `/app/index.html` |
| 88 | + |
| 89 | +### Redirect an old URL to a new place |
| 90 | + |
| 91 | +The `301` status is a permanent redirect, this is the default status code used when no code is specified. |
| 92 | +The two rules below mean the same thing: |
| 93 | + |
| 94 | +```plaintext |
| 95 | +/old/docs.html /new/documentation.html |
| 96 | +/old/docs.html /new/documentation.html 301 |
| 97 | +``` |
| 98 | + |
| 99 | +The `302` status is commonly used for temporary redirects. |
| 100 | + |
| 101 | +```plaintext |
| 102 | +/home /under-construction.html 302 |
| 103 | +``` |
| 104 | + |
| 105 | +For advanced and catch-all redirects, see [Placeholders](#placeholders). |
| 106 | + |
| 107 | +### Add a custom 404 page to your website |
| 108 | + |
| 109 | +Since the `_redirects` is evaluated only when requested path does not exist, |
| 110 | +it is possible to define a custom 404 page for your website: |
| 111 | + |
| 112 | +```plaintext |
| 113 | +/* /custom-404.html 404 |
| 114 | +``` |
| 115 | + |
| 116 | +With the above rule, opening `/this-does-not-exist` will return HTTP 404 Not Found error response with the payload of a custom error page defined in `custom-404.html`. |
0 commit comments