GitLab Pages redirects
DETAILS: Tier: Free, Premium, Ultimate Offering: SaaS, self-managed
- Introduced in GitLab Pages 1.25.0 and GitLab 13.4 behind a feature flag, disabled by default.
- Became enabled by default in GitLab 13.5.
In GitLab Pages, you can configure rules to forward one URL to another using Netlify style HTTP redirects.
Not all special options offered by Netlify are supported.
Feature | Supported | Example |
---|---|---|
Redirects (301 , 302 ) |
{check-circle} Yes | /wardrobe.html /narnia.html 302 |
Rewrites (200 ) |
{check-circle} Yes | /* / 200 |
Splats | {check-circle} Yes | /news/* /blog/:splat |
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 |
Force (shadowing) | {dotted-circle} No | /app/ /app/index.html 200! |
Domain-level redirects | {check-circle} Yes | 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 role | {dotted-circle} No | /admin/* 200! Role=admin |
NOTE: The matching behavior test cases 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
To create redirects, create a configuration file named _redirects
in the
public/
directory of your GitLab Pages site.
-
All paths must start with a forward slash
/
. -
A default status code of
301
is applied if no status code is provided. -
The
_redirects
file has a file size limit and a maximum number of rules per project, configured at the instance level. Only the first matching rules within the configured maximum are processed. The default file size limit is 64 KB, and the default maximum number of rules is 1,000. -
If your GitLab Pages site uses the default domain name (such as
namespace.gitlab.io/project-slug
) you must prefix every rule with the path:/project-slug/wardrobe.html /project-slug/narnia.html 302
-
If your GitLab Pages site uses custom domains, no project path prefix is needed. For example, if your custom domain is
example.com
, your_redirects
file would look like:/wardrobe.html /narnia.html 302
Files override redirects
Files take priority over redirects. If a file exists on disk, GitLab Pages serves
the file instead of your redirect. For example, if the files hello.html
and
world.html
exist, and the _redirects
file contains the following line, the redirect
is ignored because hello.html
exists:
/project-slug/hello.html /project-slug/world.html 302
GitLab does not support Netlify force option 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 in GitLab 14.3.
- Enabled on GitLab.com.
- Enabled on self-managed in GitLab 14.6.
To create a redirect, add a rule that includes a from
path, a to
path,
and an HTTP status code:
# 301 permanent redirect
/old/file.html /new/file.html 301
# 302 temporary redirect
/old/another_file.html /new/another_file.html 302
Rewrites
- Introduced in GitLab 14.3 with a flag named
FF_ENABLE_PLACEHOLDERS
. Disabled by default.- Enabled on GitLab.com and self-managed in GitLab 15.2.
Provide a status code of 200
to serve the content of the to
path when the
request matches the from
:
/old/file.html /new/file.html 200
This status code can be used in combination with splat rules to dynamically rewrite the URL.
Domain-level redirects
- Introduced in GitLab 16.8 with a flag named
FF_ENABLE_DOMAIN_REDIRECT
. Disabled by default.- Enabled on GitLab.com in GitLab 16.9.
FLAG:
On self-managed GitLab, by default this feature is not available.
To make it available, an administrator can enable the feature flag named FF_ENABLE_DOMAIN_REDIRECT
.
On GitLab.com, this feature is available.
To create a domain-level redirect, add a domain-level path (beginning with http://
or https://
) to either:
- The
to
path only. - The
from
andto
paths.
The supported HTTP status codes are 301
and 302
:
# 301 permanent redirect
http://blog.example.com/file_1.html https://www.example.com/blog/file_1.html 301
/file_2.html https://www.example.com/blog/file_2.html 301
# 302 temporary redirect
http://blog.example.com/file_3.html https://www.example.com/blog/file_3.html 302
/file_4.html https://www.example.com/blog/file_4.html 302
Domain-level redirects can be used in combination with splat rules (including splat placeholders) to dynamically rewrite the URL path.
Splats
- Introduced 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
:
/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:
/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:
/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
.
index.html
Rewrite all requests to a root NOTE: If you are using GitLab Pages integration with Let's Encrypt, you must enable it before adding this rule. Otherwise, the redirection breaks the Let's Encrypt integration. For more details, see GitLab Pages issue 649.
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:
/* /index.html 200
Placeholders
- Introduced 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 placeholder is formatted as a :
character followed by a string of letters
([a-zA-Z]+
) in both the from
and to
paths:
/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, 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
:
/old/:path /new/:path
Debug redirect rules
If a redirect isn't working as expected, or you want to check your redirect syntax, visit
[your pages url]/_redirects
. The _redirects
file isn't served directly, but your browser
displays a numbered list of your redirect rules, and whether the rule is valid or invalid:
11 rules
rule 1: valid
rule 2: valid
rule 3: error: splats are not supported
rule 4: valid
rule 5: error: placeholders are not supported
rule 6: valid
rule 7: error: no domain-level redirects to outside sites
rule 8: error: url path must start with forward slash /
rule 9: error: no domain-level redirects to outside sites
rule 10: valid
rule 11: valid
Differences from Netlify 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:
# 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:
# 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:/old /new/:placeholder
Given a request to
/old
:- Netlify redirects to
/new/:placeholder
(with a literal:placeholder
). - GitLab redirects to
/new/
.
- Netlify redirects to