diff --git a/files/gitlab-config-template/gitlab.rb.template b/files/gitlab-config-template/gitlab.rb.template
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvbmZpZy10ZW1wbGF0ZS9naXRsYWIucmIudGVtcGxhdGU=..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvbmZpZy10ZW1wbGF0ZS9naXRsYWIucmIudGVtcGxhdGU= 100644
--- a/files/gitlab-config-template/gitlab.rb.template
+++ b/files/gitlab-config-template/gitlab.rb.template
@@ -2007,6 +2007,9 @@
 #   'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/"
 # }
 
+# Experimental - Enable namespace in path
+# gitlab_pages['namespace_in_path'] = false
+
 ################################################################################
 ## GitLab Pages NGINX
 ################################################################################
diff --git a/files/gitlab-cookbooks/gitlab-pages/attributes/default.rb b/files/gitlab-cookbooks/gitlab-pages/attributes/default.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvYXR0cmlidXRlcy9kZWZhdWx0LnJi..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvYXR0cmlidXRlcy9kZWZhdWx0LnJi 100644
--- a/files/gitlab-cookbooks/gitlab-pages/attributes/default.rb
+++ b/files/gitlab-cookbooks/gitlab-pages/attributes/default.rb
@@ -82,6 +82,8 @@
 default['gitlab_pages']['redirects_max_path_segments'] = nil
 default['gitlab_pages']['redirects_max_rule_count'] = nil
 default['gitlab_pages']['register_as_oauth_app'] = true
+# Experimental - Enable namespace in path
+default['gitlab_pages']['namespace_in_path'] = false
 
 # Temporarily retain support for `node['gitlab-pages'][*]` usage in
 # `/etc/gitlab/gitlab.rb`
diff --git a/files/gitlab-cookbooks/gitlab-pages/libraries/gitlab_pages.rb b/files/gitlab-cookbooks/gitlab-pages/libraries/gitlab_pages.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvbGlicmFyaWVzL2dpdGxhYl9wYWdlcy5yYg==..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvbGlicmFyaWVzL2dpdGxhYl9wYWdlcy5yYg== 100644
--- a/files/gitlab-cookbooks/gitlab-pages/libraries/gitlab_pages.rb
+++ b/files/gitlab-cookbooks/gitlab-pages/libraries/gitlab_pages.rb
@@ -29,6 +29,7 @@
       parse_gitlab_pages_daemon
       parse_secrets
       parse_automatic_oauth_registration
+      parse_namespace_in_path
     end
 
     def parse_pages_external_url
@@ -134,5 +135,20 @@
 
       LoggingHelper.warning("Writing secrets to `gitlab-secrets.json` file is disabled. Hence, not automatically registering GitLab Pages as an Oauth App. So, GitLab SSO will not be available as a login option.")
     end
+
+    def parse_namespace_in_path
+      # If GitLab Pages isn't enabled or namespace_in_path is isn't enabled, do nothing.
+      return unless Gitlab['gitlab_pages']['enable'] && Gitlab['gitlab_pages']['namespace_in_path']
+
+      Gitlab['pages_nginx']['namespace_in_path'] = Gitlab['gitlab_pages']['namespace_in_path']
+      url_scheme = Gitlab['gitlab_rails']['pages_https'] ? 'https' : 'http'
+
+      Gitlab['pages_nginx']['proxy_redirect'] = {
+        "~^#{url_scheme}://(projects\\.#{Gitlab['pages_nginx']['fqdn_regex']})/(.*)$" => "#{url_scheme}://$1/$2",
+        "~^#{url_scheme}://(.*)\\.(#{Gitlab['pages_nginx']['fqdn_regex']})/(.*)$" => "#{url_scheme}://$2/$1/$3",
+        "~^//(.*)\\.(#{Gitlab['pages_nginx']['fqdn_regex']})/(.*)$" => "/$1/$3",
+        "~^/(.*)$" => "/$namespace/$1",
+      }
+    end
   end
 end
diff --git a/files/gitlab-cookbooks/gitlab-pages/templates/default/gitlab-pages-config.erb b/files/gitlab-cookbooks/gitlab-pages/templates/default/gitlab-pages-config.erb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvdGVtcGxhdGVzL2RlZmF1bHQvZ2l0bGFiLXBhZ2VzLWNvbmZpZy5lcmI=..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItcGFnZXMvdGVtcGxhdGVzL2RlZmF1bHQvZ2l0bGFiLXBhZ2VzLWNvbmZpZy5lcmI= 100644
--- a/files/gitlab-cookbooks/gitlab-pages/templates/default/gitlab-pages-config.erb
+++ b/files/gitlab-cookbooks/gitlab-pages/templates/default/gitlab-pages-config.erb
@@ -191,3 +191,6 @@
 <%- if @headers -%>
 header=<%= @headers.join(';;') %>
 <%-end -%>
+<%- if @namespace_in_path -%>
+namespace-in-path=<%= @namespace_in_path %>
+<%-end -%>
diff --git a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMucmI=..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMucmI= 100644
--- a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
+++ b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
@@ -377,6 +377,7 @@
       pages_object_store_enabled: node['gitlab']['gitlab_rails']['pages_object_store_enabled'],
       pages_object_store_remote_directory: node['gitlab']['gitlab_rails']['pages_object_store_remote_directory'],
       pages_object_store_connection: node['gitlab']['gitlab_rails']['pages_object_store_connection'],
+      pages_namespace_in_path: node['gitlab_pages']['namespace_in_path'],
       mattermost_host: mattermost_host,
       mattermost_enabled: node['mattermost']['enable'] || !mattermost_host.nil?,
       sidekiq: node['gitlab']['sidekiq'],
diff --git a/files/gitlab-cookbooks/gitlab/templates/default/gitlab.yml.erb b/files/gitlab-cookbooks/gitlab/templates/default/gitlab.yml.erb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvZ2l0bGFiLnltbC5lcmI=..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvZ2l0bGFiLnltbC5lcmI= 100644
--- a/files/gitlab-cookbooks/gitlab/templates/default/gitlab.yml.erb
+++ b/files/gitlab-cookbooks/gitlab/templates/default/gitlab.yml.erb
@@ -436,6 +436,7 @@
     local_store:
       enabled: <%= @pages_local_store_enabled %>
       path: <%= @pages_local_store_path %>
+    namespace_in_path: <%= @pages_namespace_in_path %>
 
   ## Gravatar
   ## For Libravatar see: https://docs.gitlab.com/ee/customization/libravatar.html
diff --git a/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-location.erb b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-location.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvbmdpbngtZ2l0bGFiLXBhZ2VzLWh0dHAtY29tbW9uLWxvY2F0aW9uLmVyYg==
--- /dev/null
+++ b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-location.erb
@@ -0,0 +1,20 @@
+    # Prevent NGINX from caching pages in response to the pages `Cache-Control`
+    # header.
+    #
+    # Browsers already respect this directive and Pages can handle the request
+    # volume without help from NGINX.
+    #
+    # If this changes in the future, ensure `proxy_cache_key` is set to a value
+    # like `$scheme$host$request_uri`, as the default value does not take the
+    # Pages hostname into account, leading to incorrect responses being served.
+    #
+    # See https://gitlab.com/gitlab-org/gitlab-pages/issues/73
+    proxy_cache off;
+
+    <% if @proxy_custom_buffer_size -%>
+    proxy_buffers 8 <%= @proxy_custom_buffer_size %>;
+    proxy_buffer_size <%= @proxy_custom_buffer_size %>;
+    <% end -%>
+
+    proxy_http_version 1.1;
+    proxy_pass          http://<%= @pages_listen_proxy %>;
\ No newline at end of file
diff --git a/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-server.erb b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-server.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvbmdpbngtZ2l0bGFiLXBhZ2VzLWh0dHAtY29tbW9uLXNlcnZlci5lcmI=
--- /dev/null
+++ b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http-common-server.erb
@@ -0,0 +1,61 @@
+  server_tokens off; ## Don't show the nginx version number, a security best practice
+
+  ## Disable symlink traversal
+  disable_symlinks on;
+
+  <% if @https %>
+  ## Strong SSL Security
+  ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
+  ssl_certificate <%= @ssl_certificate %>;
+  ssl_certificate_key <%= @ssl_certificate_key %>;
+  <% if @ssl_client_certificate %>
+  ssl_client_certificate <%= @ssl_client_certificate%>;
+  <% end %>
+  <% if @ssl_verify_client %>
+  ssl_verify_client <%= @ssl_verify_client%>;
+  ssl_verify_depth <%= @ssl_verify_depth%>;
+  <% end %>
+
+  # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
+  ssl_ciphers '<%= @ssl_ciphers %>';
+  ssl_protocols  <%= @ssl_protocols %>;
+  ssl_prefer_server_ciphers <%= @ssl_prefer_server_ciphers %>;
+  ssl_session_cache  <%= @ssl_session_cache %>;
+  ssl_session_tickets <%= @ssl_session_tickets %>;
+  ssl_session_timeout  <%= @ssl_session_timeout %>;
+
+  <% if @ssl_dhparam %>
+  ssl_dhparam <%= @ssl_dhparam %>;
+  <% end %>
+
+  <% if @ssl_password_file %>
+  ssl_password_file '<%= @ssl_password_file %>';
+  <% end %>
+  <% end %>
+
+  ## Real IP Module Config
+  ## http://nginx.org/en/docs/http/ngx_http_realip_module.html
+  <% if @real_ip_header %>
+  real_ip_header <%= @real_ip_header %>;
+  <% end %>
+  <% if @real_ip_recursive %>
+  real_ip_recursive <%= @real_ip_recursive %>;
+  <% end %>
+  <% @real_ip_trusted_addresses.each do |trusted_address| %>
+  set_real_ip_from <%= trusted_address %>;
+  <% end %>
+
+  ## HSTS Config
+  ## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
+  <% unless @hsts_max_age.nil? || @hsts_max_age <= 0 %>
+  add_header Strict-Transport-Security "max-age=<%= @hsts_max_age -%>
+  <% if @hsts_include_subdomains %>; includeSubdomains<% end %>";
+  <% end %>
+
+  ## Individual nginx logs for this GitLab vhost
+  access_log  <%= @log_directory %>/gitlab_pages_access.log gitlab_access;
+  error_log   <%= @log_directory %>/gitlab_pages_error.log <%= @error_log_level%>;
+
+  # Define custom error pages
+  error_page 403 /403.html;
+  error_page 404 /404.html;
\ No newline at end of file
diff --git a/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http.conf.erb b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http.conf.erb
index 7f928488e954e735f7251251f790f66ba3145bc2_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvbmdpbngtZ2l0bGFiLXBhZ2VzLWh0dHAuY29uZi5lcmI=..b844cc882da81122de26b71a96907ab507a875f0_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvbmdpbngtZ2l0bGFiLXBhZ2VzLWh0dHAuY29uZi5lcmI= 100644
--- a/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http.conf.erb
+++ b/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-pages-http.conf.erb
@@ -23,8 +23,47 @@
 }
 <% end %>
 
+<% if @namespace_in_path %>
+## Experimental - Handle requests having namespace in path
+## See https://gitlab.com/gitlab-org/gitlab/-/issues/211677
+server {
+<% @listen_addresses.each do |listen_address| %>
+  listen <%= listen_address %>:<%= @listen_port %><% if @proxy_protocol %> proxy_protocol<% end %><% if @https %> ssl<% if @http2_enabled %> http2<% end %><% end %>;
+<% end %>
+  server_name  ~^<%= @fqdn_regex %>$;
+
+  <%= render "nginx-gitlab-pages-http-common-server.erb" %>
+
+  # Pass when namespace in path to pages daemon after the rewrite
+  location ~ ^/(?<namespace>[^/]+)/(?<project>.*)$ {
+    ## Rewrite remove namespace from path
+    rewrite ^/([^/]+)/(.*)$ /$2 break;
+
+    <% @proxy_set_headers.each do |header| %>
+      <% next if header[1].nil? %>
+      <% if header[0] == "Host" %>
+    ## Put namespace back in host from path
+    proxy_set_header <%= header[0] %> <%= "$1."+header[1] %>;
+      <% else %>
+    proxy_set_header <%= header[0] %> <%= header[1] %>;
+      <% end %>
+    <% end %>
+    proxy_set_header X-Gitlab-Namespace-In-Path $namespace;
+
+    <%= render "nginx-gitlab-pages-http-common-server.erb" %>
+
+    ## Put namespace in path from host before sending it to the user
+  <% @proxy_redirect.each do |redirect| %>
+    proxy_redirect <%= redirect[0] %> <%= redirect[1] %>;
+  <% end %>
+  }
+
+  <%= @custom_gitlab_server_config %>
+}
+<% end %>
+
 server {
 <% @listen_addresses.each do |listen_address| %>
   listen <%= listen_address %>:<%= @listen_port %><% if @proxy_protocol %> proxy_protocol<% end %><% if @https %> ssl<% if @http2_enabled %> http2<% end %><% end %>;
 <% end %>
   server_name  ~^(?<group>.*)\.<%= @fqdn_regex %>$;
@@ -26,35 +65,6 @@
 server {
 <% @listen_addresses.each do |listen_address| %>
   listen <%= listen_address %>:<%= @listen_port %><% if @proxy_protocol %> proxy_protocol<% end %><% if @https %> ssl<% if @http2_enabled %> http2<% end %><% end %>;
 <% end %>
   server_name  ~^(?<group>.*)\.<%= @fqdn_regex %>$;
-  server_tokens off; ## Don't show the nginx version number, a security best practice
-
-  ## Disable symlink traversal
-  disable_symlinks on;
-
-  <% if @https %>
-  ## Strong SSL Security
-  ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
-  ssl_certificate <%= @ssl_certificate %>;
-  ssl_certificate_key <%= @ssl_certificate_key %>;
-  <% if @ssl_client_certificate %>
-  ssl_client_certificate <%= @ssl_client_certificate%>;
-  <% end %>
-  <% if @ssl_verify_client %>
-  ssl_verify_client <%= @ssl_verify_client%>;
-  ssl_verify_depth <%= @ssl_verify_depth%>;
-  <% end %>
-
-  # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
-  ssl_ciphers '<%= @ssl_ciphers %>';
-  ssl_protocols  <%= @ssl_protocols %>;
-  ssl_prefer_server_ciphers <%= @ssl_prefer_server_ciphers %>;
-  ssl_session_cache  <%= @ssl_session_cache %>;
-  ssl_session_tickets <%= @ssl_session_tickets %>;
-  ssl_session_timeout  <%= @ssl_session_timeout %>;
-
-  <% if @ssl_dhparam %>
-  ssl_dhparam <%= @ssl_dhparam %>;
-  <% end %>
 
@@ -60,6 +70,3 @@
 
-  <% if @ssl_password_file %>
-  ssl_password_file '<%= @ssl_password_file %>';
-  <% end %>
-  <% end %>
+  <%= render "nginx-gitlab-pages-http-common-server.erb" %>
 
@@ -65,30 +72,7 @@
 
-  ## Real IP Module Config
-  ## http://nginx.org/en/docs/http/ngx_http_realip_module.html
-  <% if @real_ip_header %>
-  real_ip_header <%= @real_ip_header %>;
-  <% end %>
-  <% if @real_ip_recursive %>
-  real_ip_recursive <%= @real_ip_recursive %>;
-  <% end %>
-  <% @real_ip_trusted_addresses.each do |trusted_address| %>
-  set_real_ip_from <%= trusted_address %>;
-  <% end %>
-
-  ## HSTS Config
-  ## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
-  <% unless @hsts_max_age.nil? || @hsts_max_age <= 0 %>
-  add_header Strict-Transport-Security "max-age=<%= @hsts_max_age -%>
-<% if @hsts_include_subdomains %>; includeSubdomains<% end %>";
-  <% end %>
-
-  ## Individual nginx logs for this GitLab vhost
-  access_log  <%= @log_directory %>/gitlab_pages_access.log gitlab_access;
-  error_log   <%= @log_directory %>/gitlab_pages_error.log <%= @error_log_level%>;
-
-  # Pass everything to pages daemon
+  # Pass everything to pages daemon when namespace in host
   location / {
     <% @proxy_set_headers.each do |header| %>
     <% next if header[1].nil? %>
     proxy_set_header <%= header[0] %> <%= header[1] %>;
     <% end %>
@@ -90,6 +74,7 @@
   location / {
     <% @proxy_set_headers.each do |header| %>
     <% next if header[1].nil? %>
     proxy_set_header <%= header[0] %> <%= header[1] %>;
     <% end %>
+    proxy_hide_header X-Gitlab-Namespace-In-Path;
 
@@ -95,23 +80,4 @@
 
-    # Prevent NGINX from caching pages in response to the pages `Cache-Control`
-    # header.
-    #
-    # Browsers already respect this directive and Pages can handle the request
-    # volume without help from NGINX.
-    #
-    # If this changes in the future, ensure `proxy_cache_key` is set to a value
-    # like `$scheme$host$request_uri`, as the default value does not take the
-    # Pages hostname into account, leading to incorrect responses being served.
-    #
-    # See https://gitlab.com/gitlab-org/gitlab-pages/issues/73
-    proxy_cache off;
-
-    <% if @proxy_custom_buffer_size -%>
-      proxy_buffers 8 <%= @proxy_custom_buffer_size %>;
-      proxy_buffer_size <%= @proxy_custom_buffer_size %>;
-    <% end -%>
-
-    proxy_http_version 1.1;
-    proxy_pass          http://<%= @pages_listen_proxy %>;
+    <%= render "nginx-gitlab-pages-http-common-location.erb" %>
   }
 
@@ -116,8 +82,4 @@
   }
 
-  # Define custom error pages
-  error_page 403 /403.html;
-  error_page 404 /404.html;
-
   <%= @custom_gitlab_server_config %>
 }
diff --git a/spec/chef/cookbooks/gitlab-pages/recipes/gitlab-pages_spec.rb b/spec/chef/cookbooks/gitlab-pages/recipes/gitlab-pages_spec.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWItcGFnZXMvcmVjaXBlcy9naXRsYWItcGFnZXNfc3BlYy5yYg==..b844cc882da81122de26b71a96907ab507a875f0_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWItcGFnZXMvcmVjaXBlcy9naXRsYWItcGFnZXNfc3BlYy5yYg== 100644
--- a/spec/chef/cookbooks/gitlab-pages/recipes/gitlab-pages_spec.rb
+++ b/spec/chef/cookbooks/gitlab-pages/recipes/gitlab-pages_spec.rb
@@ -255,6 +255,7 @@
             redirects_max_path_segments: 50,
             redirects_max_rule_count: 2000,
             enable_disk: true,
+            namespace_in_path: true,
             env: {
               GITLAB_CONTINUOUS_PROFILING: "stackdriver?service=gitlab-pages",
             },
@@ -329,6 +330,7 @@
             redirects-max-path-segments=50
             redirects-max-rule-count=2000
             header=X-XSS-Protection: 1; mode=block;;X-Content-Type-Options: nosniff;;Test: Header
+            namespace-in-path=true
         EOS
 
         expect(chef_run).to render_file("/var/opt/gitlab/pages/gitlab-pages-config").with_content(expected_content)
diff --git a/spec/chef/cookbooks/gitlab/recipes/gitlab-rails/gitlab_yml/pages_spec.rb b/spec/chef/cookbooks/gitlab/recipes/gitlab-rails/gitlab_yml/pages_spec.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMvZ2l0bGFiX3ltbC9wYWdlc19zcGVjLnJi..b844cc882da81122de26b71a96907ab507a875f0_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMvZ2l0bGFiX3ltbC9wYWdlc19zcGVjLnJi 100644
--- a/spec/chef/cookbooks/gitlab/recipes/gitlab-rails/gitlab_yml/pages_spec.rb
+++ b/spec/chef/cookbooks/gitlab/recipes/gitlab-rails/gitlab_yml/pages_spec.rb
@@ -28,7 +28,8 @@
             path: "/var/opt/gitlab/gitlab-rails/shared/pages",
           },
           path: "/var/opt/gitlab/gitlab-rails/shared/pages",
-          port: nil
+          port: nil,
+          namespace_in_path: false
         )
       end
     end
@@ -42,7 +43,8 @@
             gitlab_pages: {
               access_control: true,
               artifacts_server: false,
-              external_http: ['1.2.3.4']
+              external_http: ['1.2.3.4'],
+              namespace_in_path: true
             },
             gitlab_rails: {
               pages_path: '/random/path',
@@ -65,6 +67,7 @@
               external_http: true,
               external_https: false,
               artifacts_server: false,
+              namespace_in_path: true,
               object_store: {
                 enabled: true,
                 remote_directory: 'foobar',
@@ -107,6 +110,7 @@
               external_http: false,
               external_https: false,
               artifacts_server: true,
+              namespace_in_path: false,
               object_store: {
                 enabled: true,
                 remote_directory: 'foobar',
diff --git a/spec/chef/cookbooks/gitlab/recipes/nginx_spec.rb b/spec/chef/cookbooks/gitlab/recipes/nginx_spec.rb
index 7f928488e954e735f7251251f790f66ba3145bc2_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9uZ2lueF9zcGVjLnJi..b844cc882da81122de26b71a96907ab507a875f0_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9uZ2lueF9zcGVjLnJi 100644
--- a/spec/chef/cookbooks/gitlab/recipes/nginx_spec.rb
+++ b/spec/chef/cookbooks/gitlab/recipes/nginx_spec.rb
@@ -889,6 +889,67 @@
     end
   end
 
+  context 'for namespace_in_path' do
+    before do
+      stub_gitlab_rb(
+        external_url: 'https://gitlab.localhost',
+        pages_external_url: 'https://pages.localhost'
+      )
+    end
+
+    it 'default gitlab_pages namespace_in_path setting is disabled' do
+      expect(chef_run.node['gitlab_pages']['namespace_in_path']).to eql(false)
+    end
+
+    context 'when namespace_in_path is enabled in gitlab_pages' do
+      before do
+        stub_gitlab_rb(
+          gitlab_pages: { namespace_in_path: true }
+        )
+      end
+
+      it 'applies nginx namespace_in_path settings for gitlab-pages' do
+        expect(chef_run).to render_file(http_conf['pages']).with_content { |content|
+          expect(content).to include('server {').twice
+          expect(content).to include('server_name  ~^pages\.localhost$;')
+          expect(content).to include('location ~ ^/(?<namespace>[^/]+)/(?<project>.*)$ {')
+          expect(content).to include('rewrite ^/([^/]+)/(.*)$ /$2 break;')
+          expect(content).to include('proxy_set_header Host $1.$http_host;')
+          expect(content).to include('proxy_set_header X-Gitlab-Namespace-In-Path $namespace;')
+          expect(content).to include('proxy_redirect ~^https://(projects\.pages\.localhost)/(.*)$ https://$1/$2;')
+          expect(content).to include('proxy_redirect ~^https://(.*)\.(pages\.localhost)/(.*)$ https://$2/$1/$3;')
+          expect(content).to include('proxy_redirect ~^//(.*)\.(pages\.localhost)/(.*)$ /$1/$3;')
+          expect(content).to include('proxy_redirect ~^/(.*)$ /$namespace/$1;')
+          expect(content).to include('proxy_hide_header X-Gitlab-Namespace-In-Path;')
+        }
+      end
+    end
+
+    context 'when namespace_in_path is disabled in pages_nginx' do
+      before do
+        stub_gitlab_rb(
+          gitlab_pages: { namespace_in_path: false }
+        )
+      end
+
+      it 'does not apply nginx namespace_in_path settings for gitlab-pages' do
+        expect(chef_run).to render_file(http_conf['pages']).with_content { |content|
+          expect(content).to include('server {')
+          expect(content).not_to include('server_name  ~^pages\.localhost$;')
+          expect(content).not_to include('location ~ ^/(?<namespace>[^/]+)/(?<project>.*)$ {')
+          expect(content).not_to include('rewrite ^/([^/]+)/(.*)$ /$2 break;')
+          expect(content).not_to include('proxy_set_header Host $1.$http_host;')
+          expect(content).not_to include('proxy_set_header X-Gitlab-Namespace-In-Path $namespace;')
+          expect(content).not_to include('proxy_redirect ~^https://(projects\.pages\.localhost)/(.*)$ https://$1/$2;')
+          expect(content).not_to include('proxy_redirect ~^https://(.*)\.(pages\.localhost)/(.*)$ https://$2/$1/$3;')
+          expect(content).not_to include('proxy_redirect ~^//(.*)\.(pages\.localhost)/(.*)$ /$1/$3;')
+          expect(content).not_to include('proxy_redirect ~^/(.*)$ /$namespace/$1;')
+          expect(content).to include('proxy_hide_header X-Gitlab-Namespace-In-Path;')
+        }
+      end
+    end
+  end
+
   include_examples "consul service discovery", "nginx", "nginx"
 
   context 'log directory and runit group' do