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.
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.
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.
I wonder if using :splat
instead of a regular :placeholder
would work, as the latter has /
as a delimiter
//* /:splat 308
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.
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
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.
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
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.
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.
Yes. You’re right. I’m glad we’ve found a problem and possible solutions.
Thank you, @cbrandt and @anon9246926, for participation.
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.