Issue with a _redirects file

I believe Pages automatically normalises // to / when serving content. Quite possibly the only way to replace example.com//path with example.com/path is with client-side JS.

1 Like

Not really. This is not only a front-end issue, as pages with two slashes were indexed by Google, so it has to be done on the server side

So where did Google get these paths from?

You could possibly use middleware function like

export const onRequestGet = ({ request, next }) => {

  const url = new URL(request.url)
  
  if (url.pathname.includes('//')) {
    url.pathname = url.pathname.replace(/\/\//g, '/')
    return Response.redirect(url.toString(), 302)
  }

  return next()
}

But this would run on every page request which depending on the level of traffic could eat through the free tier allowance and/or paid allowance very quickly.

2 Likes

An additional slash was added to the config on production and staging servers when a website was moved to Cloudflare. I noticed it was too late, so Google already indexed all these pages.

I can always add all these pages like static redirects, but firstly, I wanted to understand why the current solution doesn’t work.

Interesting, let me try that.

UPD: didn’t work

Just wondering, where there could be a problem, so all methods don’t work. :thinking:

I wonder if using :splat instead of a regular :placeholder would work, as the latter has / as a delimiter

//* /:splat 308
1 Like

Let it go.

Make sure everything is now built and deployed correctly. Have a sitemap.xml with all the pages in it. Make sure search engine know it is there and crawl it. The invalid links will disappear and the valid links will remain.

Edit

Why? What happened (or didn’t)? It worked for me.

1 Like

okay. I noticed that URI Normalization is a thing that caused a problem.

It needs to be raw.http.request.full_uri instead of http.request.full_uri. I just tested with a static redirect, and it works, but how to make it dynamic?

in that case page //:path redirects to /:path, so :path isn’t a variable there. How I can use a variable here? Can’t find proper documentation on Cloudflare…

* and $1 doesn’t work

I don’t know, actually :smiley:

Probably, the Normalization is also a problem there, but making it off doesn’t make any difference.

First you’re trying to use _redirects now Redirect Rules, and (perhaps even) a middleware function.

If you are using more than one of these at a time, you are never going to know what is or isn’t working.

Take 10 steps back and start fresh—one thing at a time.

1 Like

With Redirect Rules, you’d need to use the function regex_replace(), available in Business plan or higher. See example here: Single Redirects — Example rules · Cloudflare Rules docs

1 Like

Thanks, but I’m not writing about every step I take.

I have a single problem and tried a few ways to fix it. I’m moving to the following approach if the current doesn’t work, and of course, I’m rolling back settings and the code…

_redirects include nothing at the moment. I realized how to make Redirect Rules work, so why not?

It looks like _redirects is used after a URI normalization, so there is no sense in using it anymore.

1 Like

It seems that in Pages the URL Normalization is applied by default, regardless of settings in Rules > Settings. I’ve tested changing URL Normalization type, as well as turning it off, but the requested URL is always normalized to remove double slashes. You can check that by creating a Transform Rule > Modify Response Header:

When incoming requests match...
Hostname equals "pages.example.com"  << YOUR PAGES CUSTOM DOMAIN

Then
Set dynamic: 
Header name: Header-Name 
Value: http.request.uri.path

To make a redirect work, you can create the following rule:

When incoming requests match...
(http.host eq "pages.example.com" and raw.http.request.uri.path contains "//")
Then
Type: Dynamic
Expression: concat("https://pages.example.com", http.request.uri.path)
Status: 3XX

EDITED to remove the limitation to Business plans: It turns out that the concat() function is available to all plan levels and can be used in this case to successfully redirect paths beginning with double slashes. What we’re doing here is matching using the raw.http.request.uri.path, which represents the path before any normalization, but redirecting the request using http.request.uri.path, which represents the path after the normalization has occurred. So, //path is redirected to /path with the chosen 3XX status code.

cc: @Vladyslav.L @anon9246926

2 Likes

Yes. You’re right. I’m glad we’ve found a problem and possible solutions.

Thank you, @cbrandt and @anon9246926, for participation.

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.