I'm attempting to map user selected sub domains to user directories on the web folder like so:
user1 has user1.domain.com which points to /domains/user1
if accessing a subdirectory in the user's folder with a trailing slash, it works fine. without a trailing slash, it'll append the entire structure.
works fine -> user1.domain.com/folder1/
does not work -> user1.domain.com/folder1
when accessing user1.domain.com/folder1, it'll redirect the user to user1.domain.com/domains/user1/folder1
accessing user1.domain.com/folder1/ (note the trailing slash) it works fine.
when two directories deep, it works as expected
user1.domain.com/folder1/folder2 and user1.domain.com/folder1/folder2/ work without issue.
this is the existing htaccess file
#enable user subdomains
RewriteCond %{HTTP_HOST} !www\.domain\.com$[NC]
RewriteCond %{HTTP_HOST} ^(.*?)\.domain\.com$
RewriteCond %{REQUEST_URI} !domains/(.*?)
RewriteRule ^(.*) /domains/%1/$1/
any help would be appreciated.
# enable user subdomains
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+)\.domain\.com$ [NC]
RewriteRule ^(?!domains(?:$|/)).* domains/%1/$0 [L]
Don't add another trailing slash otherwise you'll end up with doubles, internally.
Related
I have the following folder structure
ROOT (loaded on domain.com)
+campaigns
|+campaign1
|-assets
|-index.php
|-campaign2
.htaccess
index.php
stuff.php
At the moment to access the website inside the folder campaign1 i would have to enter in the URL address bar: domain.com/campaigns/campaign1
What should i put in the .htaccess file so that when you put
domain.com/campaign1 the browser loads and shows everything from domain.com/campaigns/campaign1 but of course without visibly changing the URL in the address bar.
Thank you so much for your help.
You could do something like the following in the root .htaccess file using mod_rewrite. This is a general version if the "campaign" subdirectories are not known (or too many):
RewriteEngine On
# 1. Abort early if request already maps to a file or directory
RewriteRule ^campaigns/ - [L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# 2. Check if the first path-segment maps to a directory in "/campaigns` directory
# If so then internally rewrite the request to that subdirectory
RewriteCond %{DOCUMENT_ROOT}/campaigns/$1 -d
RewriteRule ^([^/]+)/ campaigns%{REQUEST_URI} [L]
Where $1 is a backreference to the captured subgroup in the RewriteRule pattern.
i would have to enter in the URL address bar: example.com/campaigns/campaign1
Since campaign1 is a directory you should be requesting campaign1/ (with a trailing slash) otherwise mod_dir is going to issue an external redirect to append the trailing slash.
when you put example.com/campaign1 the browser loads and shows everything from ...
Likewise, you should be requesting example.com/compaign1/ - with a trailing slash - and the above rule assumes that you are. It won't do anything if the trailing slash is omitted and you will get a 404. (If you are expecting third party requests where the trailing slash is omitted then you will need to manually issue a 301 redirect to append the trailing slash before the above rule.)
UPDATE:
What if i know the name of the campaign folder that goes into the campaigns folder? basically if i want to manually add the rule but campaign specific?
Yes, you can do this. In fact, if the number of campaigns you wish to rewrite in this way is limited then this may even be preferable since it avoids the filesystem check.
You may also be able to remove the second rule (second part of section#1 above) that prevents further processing should a file or directory be requested. ie. Remove the following:
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
So, instead of (or before) section#2 above you could do the following...
For a single campaign:
# 2. Rewrite campaign to "/campaigns" subdirectory
RewriteRule ^compaign1/ campaigns%{REQUEST_URI} [L]
For multiple campaigns:
# 2. Rewrite campaigns to "/campaigns" subdirectory
RewriteCond $1 =campaign1 [OR]
RewriteCond $1 =campaign2 [OR]
RewriteCond $1 =campaign3
RewriteRule ^([^/]+)/ campaigns%{REQUEST_URI} [L]
Note that it is specifically $1 =campaign1, the = is a prefix-operator on the CondPattern (2nd argument) itself. The = operator makes it an exact string match, not a regex.
Or, using a regex and alternation:
# 2. Rewrite campaigns to "/campaigns" subdirectory
RewriteCond $1 ^(campaign1|campaign2|campaign3)$
RewriteRule ^([^/]+)/ campaigns%{REQUEST_URI} [L]
(Although this could be combined into a single directive.)
UPDATE#2:
Add this before the internal rewrites to add a trailing slash at the end of the URL:
RewriteCond %{REQUEST_URI} !\.
RewriteRule !/$ %{REQUEST_URI}/ [R=301,L]
Note that all internal links must already linking to the URL with a trailing slash. This redirect is only for the benefit of search engines and third party links that might be referencing the non-canonical URL without a trailing slash.
I know this question has been asked with all variations but I still cannot find the exact answer. I have changed my domain name. All website files and urls are still the same. old domain still points so the same server and I have the following code in htaccess file.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$
RewriteRule ^(.*)$ "https\:\/\/www\.newdomain\.com\/$1" [R=301,L]
Problem is that this only redirects the old domain home page. What can I do so I don't have to add individual redirects for each page.
It sounds like you've put these directives in the wrong place in your .htaccess file. They need to go at the beginning of the file, not at the end.
These directives look typical of cPanel generated redirects. cPanel always places redirects at the end of the .htaccess file (which is often incorrect).
If you have a front-controller before this (such as that used by WordPress) then you will find that these directives will only get processed for requests to the document root (ie. the "homepage"), as all other requests will be stopped by the front-controller.
These directives can also be simplified:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com [NC]
RewriteRule (.*) https://www.newdomain.com/$1 [R=301,L]
I've removed the $ from the end of the CondPattern so as to match a FQDN (that ends in a dot).
There is also no need to backslash escape colons, slashes and dots in the RewriteRule substitution, as these characters carry no special meaning here (it's not a regex). (This unnecessary escaping is very typical of cPanel.)
I am making a website builder an I would like to make urls prettier.
The url would be for example:
https://ccc-bb.example.com => https://example.com/project/show/ccc/bb
This is my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
# prevents files starting with dot to be viewed by browser
RewriteRule /\.|^\.(?!well-known/) - [F]
# front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\-(.*)$ https://example.com/project/show/$1/$2 [L]
When I use above (https://ccc-bb.example.com) it sends me to the subdomain empty folder. The folder has only the .htaccess file.
What am I missing? I've never edited an .htaccess file and Google didn't help me (or I don't know what should I looking for).
Your first rule for dotfiles is okay but would be better the other way around, since the second part can only match the start, but the first can only match in subdirectories.
RewriteRule ^\.(?!well-known/)|/\. - [F]
Your other rule's problem is that you are expecting it to match the subdomain. RewriteRules do not operate on the entire string you see in your browser's address bar, only the path part, and in .htaccess they see even less as the leading directory is stripped off, too. To access the info you want, use a RewriteCond:
RewriteCond %{HTTP_HOST} ^([^-]++)-([^-.]++)\.example\.com$
RewriteRule ^(?!project/show/).* project/show/%1/%2/$0 [L,DPI]
(You don't need to include \.example\.com$ if your main domain contains no hyphens.)
RewriteEngine on
RewriteRule ^$ http://my-site.com/directory [R=301,L]
This redirects my root page to
http://my-site.com/directory/
(notice the trailing slash).
How can I make .htaccess omit the trailing slash when generating the URL?
This is because directory is an existing directory, this is not a rewritten url.
Use another word instead of :
RewriteEngine on
RewriteRule ^$ /mypath [R=301,L]
RewriteRule ^mypath$ /directory/ [L]
Quote from noupe.com :
The filesystem on your server will always take precedence over the
rewritten URL. For example, if you have a directory named “services”
and within that directory is a file called “design.html”, you can’t
have the URL redirect to “http://domain.com/services”. What happens is
that Apache goes into the “services” directory and doesn’t see the
rewrite instructions.
To fix this, simply rename your directory (adding an underscore to the
beginning or end is a simple way to do that).
Bonus : To remove trailing slash in every urls :
RewriteEngine On
RewriteRule ^(.*)/$ $1 [R,301,L]
I just want to remove a trailing slash from a directory. For example I want /p/page/ to show up as /p/page. It just looks better, doesn't it?
However I've tried many different kinds of mod_rewrites but none have worked or something happened.
I just want this to apply to subfolders (even better, any slash in a folder in a folder in a folder like /a/b/c), not /p/ as this may affect other parts of my site in a negative way.
You can try adding the following line to your .htaccess file:
DirectorySlash Off
That solved the problem for me a while ago. Of course if the path is only / I don't think you can get rid of it.
Copy this code in your root .htaccess file (directly under DOCUMENT_ROOT):
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^ %{REQUEST_URI}/ [L]
DirectorySlash Off
RewriteCond %{THE_REQUEST} ^GET\s(.*)/\s
RewriteRule ^ %1 [R=302,NE,L]
It will externally redirect http://localhost/blog/ to http://localhost/blog while still displaying default index.html or index.php or whatever under /blog directory.