Jason Sultana

Hi, I'm Jason! I'm the author of this blog and am a certified Microsoft Developer / AWS Architect that's addicted to good steak, good coffee and good code!

htaccess redirects to multiple subfolders

23 Nov 2020 » bash, linux, php, wordpress, htaccess, others

G’day guys!

Let’s say you’ve got a couple of different web projects on your local machine (or potentially even on a server). Each project is placed in a subdirectory from the webhost root (htdocs, public_html, etc), but sadly, each project is set up with the assumption that it’s running in the root folder. The result?

There are of course a lot of ways to fix this. On a sever, you might want to just setup a subdomain for each project that points to the project directory and load the app from the subdomain. If you’re just developing on your local machine though (probably the more likely scenario), things aren’t that simple. All hope is not lost, though! This was the situation I was in just now, and here’s what I did.

Whoah there buddy! Don’t skip on the details!

So I was working on a couple of freelance projects (both Wordpress), hosted under a local MAMP installation. Both sites had some relative urls, mostly in the CSS, that assumed that it would be running in the host root. Both were broken when being hosted in a subfolder.

Assuming that I didn’t want to do something crazy, like replace the contents of the web root folder with that of whatever project I was working on, I realised I probably could make everything work by using a unqiue host name per project, combined with a bit of .htaccess dark magic.

Step 1: Add a unique host per project

This’ll require you to edit the hosts file on your local machine. For each project you’ll be hosting, add a new line with a unique host name and point it back to your local PC at Eg:   project1.local   project2.local

Step 2: Add some dark magic

Okay, it’s not really dark magic. It’s just that us .NET devs so rarely touch htaccess that it kind of feels like it is.

  1. Open up a terminal and navigate to your host root. If you’re under MAMP like I was, then it’ll probably be /Applications/MAMP/htdocs.

  2. Create a .htaccess file (if it wasn’t already there) via vi .htaccess. This will create the file via vi, which has a bit of a quirky usage convention. If you prefer, you could use touch .htaccess and edit the file with a GUI text editor, or use nano or another command line text editor instead.

  3. Time for some magic!

Any excuse to show that meme! In all seriousness though, here it is.

RewriteEngine on
RewriteBase /

# Project 1
RewriteCond %{REQUEST_URI} !^/_project_1_dir/
RewriteCond %{HTTP_HOST} ^(www.)?project1\.
RewriteRule ^(.*)$ /_project_1_dir/$1 [L,NC]

# Project 2
RewriteCond %{REQUEST_URI} !^/_project_2_dir/
RewriteCond %{HTTP_HOST} ^(www\.)?project2\.
RewriteRule ^(.*)$ /_project_2_dir/$1 [L,NC]

Told you it was magic! Now, I’m not an htaccess guru by any means, but I can still take you through some of the basics.

RewriteCond %{REQUEST_URI} !^/_project_1_dir/

This condition will match any request where any part of the URI (the bit after the hostname) does not already match the subdirectory. In this case, my project subdirectory is named _project_1_dir. We need this line so we don’t end up creating an infinite recursive redirect.

RewriteCond %{HTTP_HOST} ^(www.)?project1\.

This condition will match any request where any part of the hostname matches project1. This part is why we needed to set up a custom host in our hosts file, so we can differentiate between the projects. The www part is probably not needed for local development, but I like to leave it there just in case the config ever gets deployed or the snippet gets used on a real website.

RewriteRule ^(.*)$ /_project_1_dir/$1 [L,NC]

This rule will replace the entire request URI (since ^(.*)$ matches everything) with the project subdirectory, followed by whatever the original request was. That’s right, if you didn’t already notice, the conditions and rules both use Regular Expressions. $1 will contain the original request.

The third part (in square brackets) are flags. I always found these confusing until I actually read the Apache docs on them. No, seriously. Read the docs, since I’m not gonna tell you what they mean here.

You can repeat those 3 lines for any other projects that you have in the root directory, and it should work fine. Before you leave though, I would like to give you one last gift.

Gift? Gimme!

Debugging .htaccess config can be a real pain in the rear, so here are two things that might help.

  1. Find the htaccess error log file. Since I was hosting under MAMP, I found it under /Applications/MAMP/logs.

  2. Try this htaccess debugger. It literally helped me find a typo in one of my rules that I just couldn’t notice by looking at it: https://htaccess.madewithlove.be/

And that’s all from me for now! Happy coding and hope you don’t spend too much time on htaccess magic!

Catch ya!