Commit 60f988e4 authored by Nathan Friend's avatar Nathan Friend Committed by Marcel Amirault

Document GitLab Pages splat and placeholder support in _redirects

parent 6df7c2bf
...@@ -298,7 +298,8 @@ control over how the Pages daemon runs and serves content in your environment. ...@@ -298,7 +298,8 @@ control over how the Pages daemon runs and serves content in your environment.
| `pages_path` | The directory on disk where pages are stored, defaults to `GITLAB-RAILS/shared/pages`. | | `pages_path` | The directory on disk where pages are stored, defaults to `GITLAB-RAILS/shared/pages`. |
| **`pages_nginx[]`** | | | **`pages_nginx[]`** | |
| `enable` | Include a virtual host `server{}` block for Pages inside NGINX. Needed for NGINX to proxy traffic back to the Pages daemon. Set to `false` if the Pages daemon should directly receive all requests, for example, when using [custom domains](index.md#custom-domains). | | `enable` | Include a virtual host `server{}` block for Pages inside NGINX. Needed for NGINX to proxy traffic back to the Pages daemon. Set to `false` if the Pages daemon should directly receive all requests, for example, when using [custom domains](index.md#custom-domains). |
| `FF_ENABLE_REDIRECTS` | Feature flag to disable redirects (enabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#disable-redirects) for more information. | | `FF_ENABLE_REDIRECTS` | Feature flag to enable/disable redirects (enabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#feature-flag-for-redirects) for more information. |
| `FF_ENABLE_PLACEHOLDERS` | Feature flag to enable/disable rewrites (disabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#feature-flag-for-rewrites) for more information. |
| `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). | | `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). |
--- ---
......
...@@ -9,62 +9,58 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -9,62 +9,58 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/24) in GitLab Pages 1.25.0 and GitLab 13.4 behind a feature flag, disabled by default. > - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/24) in GitLab Pages 1.25.0 and GitLab 13.4 behind a feature flag, disabled by default.
> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/367) in GitLab 13.5. > - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/367) in GitLab 13.5.
WARNING:
This feature might not be available to you. Check the **version history** note above for details.
In GitLab Pages, you can configure rules to forward one URL to another using In GitLab Pages, you can configure rules to forward one URL to another using
[Netlify style](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file) [Netlify style](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file)
HTTP redirects. HTTP redirects.
## Supported features Not all
[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/)
GitLab Pages only supports the are supported.
[`_redirects` plain text file syntax](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file),
and `.toml` files are not supported.
Redirects are only supported at a basic level. GitLab Pages doesn't support all
[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/).
Note that supported paths must start with a forward slash `/`.
| Feature | Supported | Example | | Feature | Supported | Example |
| ------- | --------- | ------- | | ------- | --------- | ------- |
| Redirects (`301`, `302`) | **{check-circle}** Yes | `/wardrobe.html /narnia.html 302` | [Redirects (`301`, `302`)](#redirects) | **{check-circle}** Yes | `/wardrobe.html /narnia.html 302`
| Rewrites (other status codes) | **{dotted-circle}** No | `/en/* /en/404.html 404` | | [Rewrites (`200`)](#rewrites) | **{check-circle}** Yes | `/* / 200` |
| [Splats](https://docs.netlify.com/routing/redirects/redirect-options/#splats) | **{dotted-circle}** No | `/news/* /blog/:splat` | | [Splats](#splats) | **{check-circle}** Yes | `/news/* /blog/:splat` |
| Placeholders | **{dotted-circle}** No | `/news/:year/:month/:date/:slug /blog/:year/:month/:date/:slug` | | [Placeholders](#placeholders) | **{check-circle}** Yes | `/news/:year/:month/:date /blog-:year-:month-:date.html` |
| Rewrites (other than `200`) | **{dotted-circle}** No | `/en/* /en/404.html 404` |
| Query parameters | **{dotted-circle}** No | `/store id=:id /blog/:id 301` | | Query parameters | **{dotted-circle}** No | `/store id=:id /blog/:id 301` |
| Force ([shadowing](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)) | **{dotted-circle}** No | `/app/ /app/index.html 200!` | | Force ([shadowing](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)) | **{dotted-circle}** No | `/app/ /app/index.html 200!` |
| Domain-level redirects | **{dotted-circle}** No | `http://blog.example.com/* https://www.example.com/blog/:splat 301` | | Domain-level redirects | **{dotted-circle}** No | `http://blog.example.com/* https://www.example.com/blog/:splat 301` |
| Redirect by country or language | **{dotted-circle}** No | `/ /anz 302 Country=au,nz` | | Redirect by country or language | **{dotted-circle}** No | `/ /anz 302 Country=au,nz` |
| Redirect by role | **{dotted-circle}** No | `/admin/* 200! Role=admin` | | Redirect by role | **{dotted-circle}** No | `/admin/* 200! Role=admin` |
NOTE:
The [matching behavior test cases](https://gitlab.com/gitlab-org/gitlab-pages/-/blob/master/internal/redirects/matching_test.go)
are a good resource for understanding how GitLab implements rule matching in
detail. Community contributions are welcome for any edge cases that aren't included in
this test suite!
## Create redirects ## Create redirects
To create redirects, To create redirects, create a configuration file named `_redirects` in the
create a configuration file named `_redirects` in the `public/` directory of your `public/` directory of your GitLab Pages site.
GitLab Pages site.
If your GitLab Pages site uses the default domain name (such as Note that:
`namespace.gitlab.io/projectname`) you must prefix every rule with the project name:
```plaintext - All paths must start with a forward slash `/`.
/projectname/redirect-portal.html /projectname/magic-land.html 301 - A default status code of `301` is applied if no [status code](#http-status-codes) is provided.
/projectname/cake-portal.html /projectname/still-alive.html 302 - The `_redirects` file has a file size limit of 64KB and a maximum of 1,000 rules per project.
/projectname/wardrobe.html /projectname/narnia.html 302 Only the first 1,000 rules are processed.
/projectname/pit.html /projectname/spikes.html 302 - If your GitLab Pages site uses the default domain name (such as
``` `namespace.gitlab.io/projectname`) you must prefix every rule with the project name:
If your GitLab Pages site uses [custom domains](custom_domains_ssl_tls_certification/index.md), ```plaintext
no project name prefix is needed. For example, if your custom domain is `example.com`, /projectname/wardrobe.html /projectname/narnia.html 302
your `_redirect` file would look like: ```
```plaintext - If your GitLab Pages site uses [custom domains](custom_domains_ssl_tls_certification/index.md),
/redirect-portal.html /magic-land.html 301 no project name prefix is needed. For example, if your custom domain is `example.com`,
/cake-portal.html /still-alive.html 302 your `_redirects` file would look like:
/wardrobe.html /narnia.html 302
/pit.html /spikes.html 302 ```plaintext
``` /wardrobe.html /narnia.html 302
```
## Files override redirects ## Files override redirects
...@@ -81,6 +77,132 @@ GitLab doesn't support Netlify's ...@@ -81,6 +77,132 @@ GitLab doesn't support Netlify's
[force option](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing) [force option](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)
to change this behavior. to change this behavior.
## HTTP status codes
A default status code of `301` is applied if no status code is provided, but
you can explicitly set your own. The following HTTP codes are supported:
- **301**: Permanent redirect.
- **302**: Temporary redirect.
- **200**: Standard response for successful HTTP requests. Pages
serves the content in the `to` rule if it exists, without changing the URL in
the address bar.
## Redirects
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
> - Enabled on GitLab.com.
> - Enabled by default in self-managed GitLab behind the [`FF_ENABLE_REDIRECTS` feature flag](#feature-flag-for-redirects).
To create a redirect, add a rule that includes a `from` path, a `to` path,
and an [HTTP status code](#http-status-codes):
```plaintext
# 301 permanent redirect
/old/file.html /new/file.html 301
# 302 temporary redirect
/old/another_file.html /new/another_file.html 302
```
## Rewrites
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
> - Enabled on GitLab.com.
> - Disabled by default in self-managed GitLab behind the [`FF_ENABLE_PLACEHOLDERS` feature flag](#feature-flag-for-rewrites).
Provide a status code of `200` to serve the content of the `to` path when the
request matches the `from`:
```plaintext
/old/file.html /new/file.html 200
```
This status code can be used in combination with [splat rules](#splats) to dynamically
rewrite the URL.
## Splats
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
A rule with an asterisk (`*`) in its `from` path, known as a splat, matches
anything at the start, middle, or end of the requested path. This example
matches anything after `/old/` and rewrites it to `/new/file.html`:
```plaintext
/old/* /new/file.html 200
```
### Splat placeholders
The content matched by a `*` in a rule's `from` path can be injected into the
`to` path using the `:splat` placeholder:
```plaintext
/old/* /new/:splat 200
```
In this example, a request to `/old/file.html` serves the contents of `/new/file.html`
with a `200` status code.
If a rule's `from` path includes multiple splats, the value of the first splat
match replaces any `:splat`s in the `to` path.
### Splat matching behavior
Splats are "greedy" and match as many characters as possible:
```plaintext
/old/*/file /new/:splat/file 301
```
In this example, the rule redirects `/old/a/b/c/file` to `/new/a/b/c/file`.
Splats also match empty strings, so the previous rule redirects
`/old/file` to `/new/file`.
### Rewrite all requests to a root `index.html`
Single page applications (SPAs) often perform their own routing using
client-side routes. For these applications, it's important that _all_ requests
are rewritten to the root `index.html` so that the routing logic can be handled
by the JavaScript application. You can do this with a `_redirects`
rule like:
```plaintext
/* /index.html 200
```
## Placeholders
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/458) in GitLab 14.3.
Use placeholders in rules to match portions of the requested URL and use these
matches when rewriting or redirecting to a new URL.
A placehold is formatted as a `:` character followed by a string of letters
(`[a-zA-Z]+`) in both the `from` and `to` paths:
```plaintext
/news/:year/:month/:date/:slug /blog/:year-:month-:date-:slug 200
```
This rule instructs Pages to respond to a request for `/news/2021/08/12/file.html` by
serving the content of `/blog/2021-08-12-file.html` with a `200`.
### Placeholder matching behavior
Compared to [splats](#splats), placeholders are more limited in how much content
they match. Placeholders match text between forward slashes
(`/`), so use placeholders to match single path segments.
In addition, placeholders do not match empty strings. A rule like the following
would **not** match a request URL like `/old/file`:
```plaintext
/old/:path /new/:path
```
## Debug redirect rules ## Debug redirect rules
If a redirect isn't working as expected, or you want to check your redirect syntax, visit If a redirect isn't working as expected, or you want to check your redirect syntax, visit
...@@ -103,8 +225,49 @@ rule 10: valid ...@@ -103,8 +225,49 @@ rule 10: valid
rule 11: valid rule 11: valid
``` ```
## Disable redirects ## Differences from Netlify's implementation
Most supported `_redirects` rules behave the same in both GitLab and Netlify.
However, there are some minor differences:
- **All rule URLs must begin with a slash:**
Netlify does not require URLs to begin with a forward slash:
```plaintext
# Valid in Netlify, invalid in GitLab
*/path /new/path 200
```
GitLab validates that all URLs begin with a forward slash. A valid
equivalent of the previous example:
```plaintext
# Valid in both Netlify and GitLab
/old/path /new/path 200
```
- **All placeholder values are populated:**
Netlify only populates placeholder values that appear in the `to` path:
```plaintext
/old /new/:placeholder
```
Given a request to `/old`:
- Netlify redirects to `/new/:placeholder` (with a
literal `:placeholder`).
- GitLab redirects to `/new/`.
## Features behind feature flags
Some Pages features are behind feature flags.
### Feature flag for redirects
FLAG:
Redirects in GitLab Pages is under development, and is deployed behind a feature flag Redirects in GitLab Pages is under development, and is deployed behind a feature flag
that is **enabled by default**. that is **enabled by default**.
...@@ -126,3 +289,28 @@ For [source installations](../../../administration/pages/source.md), define the ...@@ -126,3 +289,28 @@ For [source installations](../../../administration/pages/source.md), define the
export FF_ENABLE_REDIRECTS="false" export FF_ENABLE_REDIRECTS="false"
/path/to/pages/bin/gitlab-pages -config gitlab-pages.conf /path/to/pages/bin/gitlab-pages -config gitlab-pages.conf
``` ```
### Feature flag for rewrites
FLAG:
Rewrites in GitLab Pages is under development, and is deployed behind a feature flag
that is **disabled by default**.
To enable rewrites, for [Omnibus installations](../../../administration/pages/index.md), define the
`FF_ENABLE_PLACEHOLDERS` environment variable in the
[global settings](../../../administration/pages/index.md#global-settings).
Add the following line to `/etc/gitlab/gitlab.rb` and
[reconfigure the instance](../../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure):
```ruby
gitlab_pages['env']['FF_ENABLE_PLACEHOLDERS'] = 'true'
```
For [source installations](../../../administration/pages/source.md), define the
`FF_ENABLE_PLACEHOLDERS` environment variable, then
[restart GitLab](../../../administration/restart_gitlab.md#installations-from-source):
```shell
export FF_ENABLE_PLACEHOLDERS="true"
/path/to/pages/bin/gitlab-pages -config gitlab-pages.conf
```
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment