My site structure is main site example
and two subfolders sites /es/
and /en/
example
redirects => example/es/
and example/en/
is the English version.
What is wrong?
The following:
example/<non-existing-page>
redirects => example/es/
Some part of this main redirect is causing that every non-existing page inside mysite (This site is empty) is redirected to the main page which is in the subdomain example/es/
instead of getting a 404 error. I see where is the problem but I don't know how to modify the rule.
My redirect in the .htaccess
file:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# Main Redirect
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^/?$ "https\:\/\/example\\/es\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^index\.html$ "https\:\/\/example\\/es\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^indexingles\.html$ "https\:\/\/example\\/en\/" [R=301,L]
Works perfect for the following:
- Is perfect that
example/index.php
redirects =>example/es
- Is perfect that
index.html
redirects =>example/es
- Is perfect that
indexingles.html
redirects =>example/en
Summarizing
Every URL that has example/<non-existent-page>
redirects to the main page: example/es/
.
It's wrong that a non-existent-page doesn't get a 404 error. I have to change this and I don't know how.
If the URL is example/es/<non-existent-page>
it gets a 404 error which is OK.
If the URL is example/en/<non-existent-page>
it gets a 404 error which is OK.
Note:
If somebody else is going to use this redirect, I want to add that Mr. White redirection is working just fine. However order to make the redirection of the backend to work properly I had to delete Wordfence plugin.
My site structure is main site example
and two subfolders sites /es/
and /en/
example
redirects => example/es/
and example/en/
is the English version.
What is wrong?
The following:
example/<non-existing-page>
redirects => example/es/
Some part of this main redirect is causing that every non-existing page inside mysite (This site is empty) is redirected to the main page which is in the subdomain example/es/
instead of getting a 404 error. I see where is the problem but I don't know how to modify the rule.
My redirect in the .htaccess
file:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# Main Redirect
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^/?$ "https\:\/\/example\\/es\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^index\.html$ "https\:\/\/example\\/es\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\$
RewriteRule ^indexingles\.html$ "https\:\/\/example\\/en\/" [R=301,L]
Works perfect for the following:
- Is perfect that
example/index.php
redirects =>example/es
- Is perfect that
index.html
redirects =>example/es
- Is perfect that
indexingles.html
redirects =>example/en
Summarizing
Every URL that has example/<non-existent-page>
redirects to the main page: example/es/
.
It's wrong that a non-existent-page doesn't get a 404 error. I have to change this and I don't know how.
If the URL is example/es/<non-existent-page>
it gets a 404 error which is OK.
If the URL is example/en/<non-existent-page>
it gets a 404 error which is OK.
Note:
If somebody else is going to use this redirect, I want to add that Mr. White redirection is working just fine. However order to make the redirection of the backend to work properly I had to delete Wordfence plugin.
Share Improve this question edited Feb 5, 2021 at 17:50 Irene asked Feb 1, 2021 at 19:04 IreneIrene 235 bronze badges 1 |1 Answer
Reset to default 1Every URL that has
example/<non-existent-page>
redirects to the main page:example/es/
.
This is presumably being done by WordPress itself, as there is nothing in what you've posted (in .htaccess
) that is doing this.
You probably need to add an additional "wildcard" redirect to redirect /<anything>
(except for /es
and /en
) to /es/<anything>
. For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^(es|en)($|/) https://example/es%{REQUEST_URI} [R=301,L]
This will naturally encompass the root redirect (your first rule) as well. However, this redirect will need to go after the other two specific redirects that remove index.html
and indexingles.html
respectively.
The RewriteCond
directive that checks against the REDIRECT_STATUS
environment variable is necessary to ensure that only direct requests are redirected and not rewritten requests to index.php
(the WP front-controller). This preventing a redirect loop. The REDIRECT_STATUS
env var is not set on direct requests but set to "200" (as in "200 OK" HTTP response status) after the first successful rewrite. The alternative would be to include index.php
in the alternation subpattern, however, that wouldn't then canonicalise direct requests to index.php
itself.
There is no need to backslash escape the slashes, dots and colons in the RewriteRule
substitution since these characters have no special meaning here.
Also, there is no need for the conditions (RewriteCond
directives) unless you have multiple domains. But even if you are, this can be simplified to a single condition. For example:
RewriteCond %{HTTP_HOST} ^(www\.)?example\ [NC]
You should test first with 302 (temporary) redirects in order to avoid potential caching issues. And only change to a 301 (permanent) when you are sure this is working OK. However, language redirects like this should probably be temporary anyway.
So, in summary, you should replace your existing redirect directives with the following:
RewriteEngine On
# Remove "index.html" and redirect to "/es/"
RewriteRule ^index\.html$ https://example/es/ [R=301,L]
# Remove "indexingles.html" and redirect to "/en/"
RewriteRule ^indexingles\.html$ https://example/en/ [R=301,L]
# Everything else default to "/es/<anything>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^(es|en)($|/) https://example/es%{REQUEST_URI} [R=301,L]
UPDATE: What its not working is:
https://example/wp-admin/network/
redirected you too many times.
I think you'll probably need to exclude any URL that starts /wp-admin
(and /wp-login.php
and /phpmyadmin
) from the last redirect. Change the last rule to read:
# Everything else default to "/es/<anything>"
# With some exceptions...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^(es|en|wp-admin|wp-login\.php|phpmyadmin)($|/) https://example/es%{REQUEST_URI} [R=301,L]
You could also consider excluding any URL that already maps to a physical file (ie. -f
). And if more exclusions are required then consider adding additional RewriteCond
directives instead. For example:
# Everything else default to "/es/<anything>"
# With some exceptions...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !^/wp-login\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(es|en|wp-admin|phpmyadmin)($|/) https://example/es%{REQUEST_URI} [R=301,L]
Note that the REQUEST_URI
server variable includes the slash prefix on the URL-path, but the URL-path matched by the RewriteRule
pattern does not.
example
? – MrWhite Commented Feb 1, 2021 at 20:30