301 Redirects and non-www to www Canonical Problems (Yii Framework) - .htaccess

The 301 redirection of non-www to www doesn't work completely on my site (CMS: Yii Framework).
Here's my htaccess:
IndexIgnore */*
RewriteEngine on
#if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
It's ok when I type example.com, the redirection points to www.example.com but when I type "example.com/tag/world" the redirection doesn't work. I don't know why. :/
And when I type example.com/news (category) I don't get the redirection to www.example.com/news, the URL redirects to example.com/index.php/.
In the urlManager section of the file main.php you can see below the code for the tag and the category:
'tag/<titre>'=>'frontend/categorie/tag',
'chroniqueur/<titre>'=>'frontend/categorie/liste',
'<titre>'=>array('frontend/categorie/index', 'urlSuffix'=>'/'),
'search/<titre>'=>'frontend/search/index',
Do I have to modify or change something ? I'm new on Yii.

Move 301 rule before other rule:
IndexIgnore */*
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

Related

.htaccess 301 redirect only work for 1 new link

I have .htaccess file with redirect 301 on it and placed right under the rewriteengine
<IfModule mod_rewrite.c>
RewriteEngine On
#now this is the redirect
Redirect 301 /blog.php?slug=konsolidasi-tanah-frequently-asked-questions https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah
Redirect 301 /blog/2021/02/11/konsolidasi-tanah-frequently-asked-questions https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah
</IfModule>
only 2nd redirect works, the one with the get method are not redirected, am i doing wrong?
EDITED :
this is my entire mod rewrite :
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
RewriteRule ^index\.php$ / [R=301,L]
RewriteRule ^(.*)/index\.php$ /$1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
# Permanent URL redirect
Redirect 301 /blog.php?slug=konsolidasi-tanah-frequently-asked-questions https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah
# Permanent URL redirect
Redirect 301 /blog/2021/02/11/konsolidasi-tanah-frequently-asked-questions https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah
Redirect 301 /blog.php?slug=konsolidasi-tanah-frequently-asked-questions /blog/2021/02/11/pengertian-konsolidasi-tanah
RewriteRule ^blog/2021/02/11/pengertian-konsolidasi-tanah /blog.php?slug=konsolidasi-tanah-frequently-asked-questions
It is usually not a good idea to mix RewriteRule and Redirect 301 directives. They can conflict with each other in unexpected ways. You depend of RewriteRule so you should implement your redirects with more of them.
Redirect 301 can't redirect based on query strings (?...) in the URL, so you need to implement RewriteRules for that redirect anyway.
When you have rules for redirecting specific URLs, they should go at the top of the .htaccess file so that they take precedence over the other more general rules.
I would recommend disabling the directory index because I fear it would conflict with your RewriteRule ^index\.php$ / [R=301,L] rule.
I don't see RewriteEngine On in your .htaccess file, despite that your snippet you posted to start with has it.
Try this as your .htaccess:
# Disable index.html, index.php default functionality
DirectoryIndex disabled
RewriteEngine On
# Permanent URL redirect
RewriteCond %{QUERY_STRING} ^slug=konsolidasi-tanah-frequently-asked-questions$
RewriteRule ^blog\.php$ https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah [R=301,L]
RewriteRule ^blog/2021/02/11/konsolidasi-tanah-frequently-asked-questions$ https://jpi.or.id/blog/2021/02/11/pengertian-konsolidasi-tanah [R=301,L]
# Forward URLs without .php extension to existing PHP file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
# Redirect index.php URLs to the directory
RewriteRule ^index\.php$ / [R=301,L]
RewriteRule ^(.*)/index\.php$ /$1/ [R=301,L]
# Use index.php as a front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

htaccess RewriteRule and Redirect 301 interfering with one another

My .htaccess file includes this, which allows the URL structure in my ExpressionEngine site to function:
RewriteRule ^(.*)$ /index.php?/$1 [L]
However, it is interfering with what I'm trying to do here, redirecting an old page:
Redirect 301 /old-url/ /
This is what I see in my browser address after I load the /old-url/ address:
https://www.domain.test/?/old-url/
If I take out the RewriteRule, my Redirect 301 works, but all the navigation in the site breaks. Is there some way for me to make an exception where I want to redirect old URLs? I have inherited someone else's work in this case.
Edit: here is my entire .htaccess file content:
RewriteEngine On
Redirect 301 /in-loving-memory-of-our-partners /
Redirect 301 /in-loving-memory-of-our-partners/ /
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^sitemap\.xml$ /sitemap/xml [NC,L]
RewriteCond $1 !^(assets|emergency|portalimages|images|system|themes|test|AUL|swfs|favicon\.ico|robots\.txt|index\.php) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteRule ^(.well-known) - [L]

htaccess rewrite subdirectory as root and also redirect if the subdirectory is accessed directly

I have URLs like this
https://example.com/public
https://example.com/public/faq.php
I want to rewrite it like this
https://example.com
https://example.com/faq.php
Rule I am using is this
RewriteEngine On
Options +FollowSymLinks
RewriteRule ^$ public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ public/$1 [L]
This rule works very well but it doesn't redirect if someone access "https://example.com/public/" or "https://example.com/public/faq.php"
Solution
I have found a workaround for this. I have added below code to redirect if the public directory will be accessed directly.
RewriteCond %{THE_REQUEST} /public [NC]
RewriteRule .* / [L,R]

.htaccess redirect does not working well

I want to redirect main domain "example.com" to to subdirectory "sub" with .htaccess. I have .htaccess file with this content:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/sub/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /sub/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ sub/index.php [L]
and it works ok if I enter example.com or www.example.com in address bar in web browser, but if I enter example.com/index.php or www.example.com/index.php that's not working and it goes to primary folder, not in subfolder sub.
What I am doing wrong?
This works fine:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?example\.org$ [NC]
RewriteCond %{REQUEST_URI} !^/sub/
RewriteRule ^(.*)$ /sub/$1 [L]
Also, you can use this for testing your htaccess
Why don't you set up your redirect in the index.php file? Your .htaccess file doesn't have a condition for that. Since you are hitting the page directly.
As per my comment below, put this into your index.php page:
header("Location: http://example.com/sub/index.php");
die();

How to change .htaccess file to redirect to www, not http?

Below is the code in my .htaccess file. How do I change it to redirect visitors to https://www and not http://.
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
Immediately after the RewriteEngine On directive, place the following:
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !www\.
RewriteRule .* https://www.example.com%{REQUEST_URI} [R=301,L]
This will handle both the http to https and non-www to www redirection. Note that external redirections should generally come before internal rewrites (which is what you currently have).

Resources