Categories
Apache mod-rewrite and htaccess related Articles

How to remove specific query string from URLs using htaccess

In this article I will show you how we can remove a specific part of URL using RewriteRule directive in an htaccess file.
This article is based on a StackOverflow question asked by an Apache user. I will explain how you can write RewriteRule to trim a specific part of URL.
Let’s first take the real example from the question asked on StackOverflow.
The question poster wanted to remove /?569/ from their original URL which looked something like
https://www.example.com/lang/part1/?569/item1/item2/item3/product.html .
As you can see the URL part the OP wanted to remove starts with a “question mark” ? so it’s part of “URL query string” .
The entire string after ? is part of query string but as the OP asked, we just have to remove the specific segment.

To trim this query string part , we will write a RewriteRule and a Condition in our our htaccess.

We will use the following condition to check the Query String part in the URL :

RewriteCond %{QUERY_STRING} ^569/(.+)$ [NC]

Since we have to trim only the specific part “?569/” we use the pattern ^569/(.+) that matches a query string starting with 569/ and the (.+) matches other characters and saves the match as we will use it in the target URL.
The RewriteRule we will use here is :

RewriteRule ^lang/part1/$ https://www.example.com/lang/part1/%1? [R=301,L]

The pattern of the rule matches the URL path which is /lang/part1/ .
In the Rule’s destination you can see the URL is now “https://www.example.com/lang/part1/%1?” . The %1 is the match from the RewriteCond regex and the ? at the end is there to trim the Old query string so that our final URL could look clean and something like
https://www.example.com/lang/part1/item1/item2/item3/product.html .

The following is the complete Rule to remove the specific part from the mentioned URL :

RewriteEngine on
RewriteCond %{QUERY_STRING} ^569/(.+)$ [NC]
RewriteRule ^lang/part1/$ https://www.example.com/lang/part1/%1? [R=301,L]

Categories
Apache mod-rewrite and htaccess related Articles

How to fix it when there are two RewriteRules of identical patterns in htaccess

Are you struggling to fix your RewriteRules with two identical patterns?
In this article I will show you how to fix it when you have two RewriteRules with same patterns in an htaccess file.
I know it’s a bit complicated for people who are new to htaccess to understand why their Rule failed but this article will explain the reason and provide you a working solution.

Rewrite engine reads rules from top to bottom

In an htaccess or server.config files , rules are read from top to bottom . Not just RewriteRule but all directives are read in this order. In your htaccess file the first line is read first.
Suppose, your htaccess file has the following two rules :

RewriteRule ^foo /index.php [L]
RewriteRule ^foot /index.php [L]

As you can see we have two rules of the same pattern, the first rule has a catch-all pattern and it also matches the URL path foot .
The second rule is there created to match a request that starts with foot but for your surprise, the server will only read the first rule wether you type
foo or foot.
The reason behind this is that the both rules have identical patterns.

The ^foo in regex is same as ^foot . It matches anything after the last “o” character.

Fix RewriteRules with identical patterns

You can fix the above rules easily by swapping it. Change the order of the rules ,

RewriteRule ^foot /index.php [L]
RewriteRule ^foo /index.php [L]

Now if you visit foo the engine will read the correct second rule
because the first one doesn’t match it.

Change the form of your URIs

If you have two RewriteRules of the same pattern then the most common issue you will face is Your first rule will be matched while the second one will have no effect.
The following is an example of RewriteRules with identical patterns :

RewriteEngine on
RewriteRule (.*) /index.php [L]
RewriteRule (.*) /index2.php [L]

Only the first rule above will be read by server. To fix this you need to change the form of your URIs. Change the regex of the first pattern to ^first/(.*)$ so that any URIs starting with /first can point to the correct index.php file and other URIs to index2.php.
first is just an example here , you change the pattern to whatever URI you want to set .

Categories
Apache mod-rewrite and htaccess related Articles

URL redirection based on server date/time headers | htaccess

Htaccess URL redirection based on server date and time variables

Hello Apache users!
I am here again with a new
interesting article about URL rewriting.
Today , in this article I will show you how we can rewrite/redirect URLs based on several Date and Time headers.
Apache mod-rewrite has several
predefined server variables to work with date and time. If we need to redirect or rewrite our URLs on a date/time logic we can use these variables in conditions with RewriteRule.
Let’s first have a look at all the date and time variables provided by Apache mod_rewrite.

Apache Date and Time variables

  • %{TIME}
  • %{TIME_YEAR}
  • %{TIME_DAY}
  • %{TIME_MON}
  • %{TIME_HOUR}
  • %{TIME_MIN}
  • %{TIME_SEC}
  • %{TIME_WDAY}

These are all the date & time server variables provided by rewrite engine.

Variables explained

  • %{TIME} – Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) . The value of this variable looks something like 20210529073917
  • %{TIME_YEAR} – Returns the current year in YYYY format. The value of this variable looks something like 2021.
  • %{TIME_DAY} – Returns current day of the month from . Ie 29 .
  • %{TIME_MON} – Returns the current month of the year in digit format from 01 to 12 .
  • %{TIME_HOUR} – Returns the current hour in digit format from 00 to 24.
  • %{TIME_MIN} – Returns the current minute from 00 to 59 .
  • %{TIME_SEC} – Returns the current second from 00 to 59 .
  • %{TIME_WDAY} – Returns name of the current week ie “Sunday” .

URL rewriting with date & time logic

To rewrite or redirect URLs with date and time logic we can use mod-rewrite server variables . This peragraph will show you with some code examples how we can use “date and time” variables with mod_rewrite.

To redirect URLs conditionally using date and time logic here are some basic examples.
In this first example, we are writing a rule to redirect all our website URLs to example.com only if the specified condition is met ie the %{TIME_HOUR} is 05 .

RewriteEngine on
RewriteCond %{TIME_HOUR} ^05$
RewriteRule .* https://example.com [L,R]

If you have a website that is maintained on a specific day every week, say your website is maintained every Monday , and you want to automatically redirect your site URLs to a specific page /maintenance.html , you can use the following in your htaccess file :

RewriteEngine on
RewriteCond %{TIME_WDAY} ^monday$ [NC]
RewriteRule .* /maintenance.html [R,L]

The rule above will do a temporary redirection to “maintenance.html” if the specified condition is met. We are using R
instead of R=301 because we want a temporary redirection that is valid only for the current day.


If you need to redirect your site visitors to maintenance.html page every Monday on 8PM , you could use the following :

RewriteEngine on
RewriteCond %{TIME_WDAY} ^monday$ [NC]
RewriteCond %{TIME_HOUR} ^20$
RewriteRule .* /maintenance.html [R,L]

The rule above is simple and easy to understand. We have used two date time conditions to determine the exact week day and hour on which we will put the redirection.

I hope this article was helpful. If there is something that you didn’t understand or have any questions , you could post a comment below. I always reply as soon as I can.
Thanks for reading this!

Categories
Apache mod-rewrite and htaccess related Articles

Block bad referer domains using htaccess to improve backlink profile

Block bad referer domains using htaccess

Last night when I checked my friend’s domain on ahrefs tools I was amazed to see the backlink profile of his domain. He had a bad SEO backlink profile, domain with just 2.5 DR even with 125 referering domains and 1600 backlinks.
When I analyzed the backlink profile , I saw some strange random spam domains . There were multiple domains with the same name and with different extensions pointing to my friends domain.
The main reason why the domain ratting decreased was the bad referer domains using the backlink. When I checked further I noticed there were 97 raferer domains with 0 DR and 0UR (UrlRatting). DR “Domain Ratting” is the domain trust score. DR can be anything from 0 to 100 . The less the DR the less trusted domain it is. If your domain has 0 DR then your chances of ranking in search engines are lower. DR increases when a domain with good DR points to your domain .

But if a bad domain (bad domain is a domain with 0 DR/UR or it can be a domain flaged as spam by search engines) points to your domain , it can decrease your domain ratting and prevent your domain from being indexed by search engines. So it’s always important to take care of your referer domains and backlinks. You can use free backlink checker tool to keep an eye on your backlink profile.

Block bad referer domains using htaccess

To block bad referer domains the best and the easiest option is RewriteRule .
Just create a list of referer Domains you want to block and use RewriteRule in htaccess to redirect those domain to 403 forbidden error page. By using a 403 redirect those domains won’t be able to redirect traffic to your site and you can improve your damaged backlink profile .

To block a single referer domain , you can use the following code in your htaccess :

RewriteEngine on
RewriteCond %{HTTP_REFERER} baddomain\.com [NC]
RewriteRule .* - [R=403,L]

Make sure to replace baddomain.com with the domain name you want to block.

If you want block referering domains, you can use the exact same Rule with [OR] conditions.
The following rule blocks 3 referer domains , if you have more domains you can tweak the code accordingly . But just keep in mind that you don’t have to use OR flag with the last condition :

RewriteEngine on
RewriteCond %{HTTP_REFERER} baddomain\.com [NC,OR]
RewriteCond %{HTTP_REFERER} baddomain2\.com [NC,OR]
RewriteCond %{HTTP_REFERER} baddomain\.com [NC]
RewriteRule .* - [R=403,L]

With the rules shown above you can easily block bad referers from your website.

I hope this article was helpful. Thanks so much for reading.

Categories
Apache mod-rewrite and htaccess related Articles

How to verify whether the htaccess file is working on Apache server

Is htaccess working on apache
Do you want to know whether the htaccess file is working or not working on your Apache server?
In this article today, I will show you how to verify whether the htaccess is being read by your server. For many new Apache users who are beginners in htaccess and URL rewriting this can be a bit complicated to know if the htaccess they are using is working so I decided to write this Article to help them.

How to know wether your htaccess is working on Apache server.

An htaccess file on apache server uses .htaccess extension by default. The file doesn’t have name just the the extension. The first thing you need to make sure is that the file name is exactly . htaccess . If it is misspelt then correct it because many new user when they create an htaccess file they either misspell the name or create file name as htaccess.txt . The correct name that the server knows of this file is .htaccess .
Also there are multiple ways to check whether your server is reading the .htaccess. There are many ways to check it but here I will include only the ones that will help you at beginner level.

The quick , easy and effective way to check wether your server is reading the htaccess file is by adding a Redirect to your htaccess file.
Open your htaccess file for writing in an editor and put the following line at the top of your htaccess :

Reditect /foobar/ https://example.com

Save the file and type the URL yoursite.com/foobar/ .
If the reditect works and the URL gets redireted to the homepage of example.com then it’s clear that your htaccess is working and being read by your Apache server.
If it still doesn’t work then the problem might be that your hosting provider has not enabled it. In that case you could ask your hosting service provider to enable it for you.

Another way to check htaccess :

You can also check your htaccess by using RewriteRule directive .
Add the following rule to your htaccess :

RewriteEngine on
RewriteRule ^foobar/$ https://example.com/ [R]

I suggest you to try this if the first method fails. Sometimes Redirect directive doesn’t work as it gets overridden by other directives, RewriteRule never fails to work , so you can try this one if the the above fails and if it also fails then ask your hosting provider.

Categories
Apache mod-rewrite and htaccess related Articles

11 useful htaccess snippets for mod_rewrite and htaccess beginners

In this article today I am going to share 10 htaccess code snippets that will help you learn some basics of how URL rewriting and htaccess works on Apache server. With the htaccess code examples and explainations on this page you will be able to modify the code examples and create your own code for htaccess.
Table of contents (10 htaccess snippets)

  1. How to enforce WWW
  2. How to redirect URL with Query String
  3. How to enforce SSL for a specific directory
  4. Allow URLs without .php
  5. How to block ip addresses
  6. How to set a custom file as index
  7. Redirect a specific directory to another directory
  8. Serve subdomain from subfolder
  9. How to redirect all URLs to index.php
  10. How to deny access to a specific directory
  11. Htaccess ErrorDocument

If you want to learn some basics of Apache mod-rewrite , you can follow this tutorial hosted on this site.

htaccess code snippets for beginners

301 Redirect non-www domain to www subdomain

If you want to redirect your non-www naked domain to www subdomain , the rule is simple , quick and easy to follow. You just need to match against your non-www (naked domain) using a RewriteCond and then use a Rule that redirects all URLs to www subdomain.
The quick rule to enforce www is here :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [NE,L,R=301]

Make sure to replace example.com with your domain name in the code above.


Redirect URL with Query string

To redirect URL query strings using RewriteRule we have to match against %{QUERY_STRING} variable in RewriteCond directive .
The RewriteRule bellow will apply to any incoming URL path of this form /foo/?q=bar .

If the path matches the Rule and the condition then it gets redireted to an external URL https://example.com/ with Redirect 301 status .
Here is the rule we are talking about :

RewriteEngine on
RewriteCond %{QUERY_STRING} ^q=bar$ [NC]
RewriteRule ^foo/$ https://example.com/? [R=301]

One thing to take note of in the rule above is a question mark “?” at the end of the target URL . It’s important as it discards the old query string from the new URL.
If you remove it the redirected URL will appear like https://example.com/?q=bar .
However if you want to pass the old query strings to the new URL, you can remove it.


Enforce SSL for a specific directory

If you want to enforce SSL for a specific directory , say Root / , then you can use the following simple rule in your . htaccess file .

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/[^/]+/?$
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]

The rule will only apply to your root directory and all its file but not subfolders. If you want the rule to enforce SSL for the entire site then you just need to remove the second RewriteCond .


Allow URLs without .php extensions

If you want to access your php files without using .php extension at the end of the URLs, then the rule is simple. You just need to rewrite your extension-less PHP files to their original versions .

RewriteEngine on
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]

This doesn’t remove php extension but makes it so that you can just visit /file instead of /file.php
.


Block specific IP addresses using RewriteRule

You can block a specific or multiple ip addresses using RewriteRule in an htaccess file.

To block a single ip address from accessing your website, you can use the following :

RewriteEngine on
RewriteCond %{REMOTE_ADDR} ^1\.0\.0\.$
RewriteRule .* - [R=403,L]

This returns a 403 forbidden error the specified ip address. To block multiple ips you can use RewriteCond directives with [OR] flag.

RewriteEngine on
RewriteCond %{REMOTE_ADDR} ^1\.0\.0\.$ [OR]
RewriteCond %{REMOTE_ADDR} ^2\.0\.0$
RewriteRule .* - [R=403,L]

You can remove multiple ips using RewriteConds with “OR” but just don’t use the OR flag with last condition.


Set a custom file as DirectoryIndex

If you need to use a different file instead of index.php or index.html as your directory handler, you can do this using a RewriteRule directive. You just need to rewrite your directory path to that file.
The code example bellow makes the demo.php your main index file for root. So you will see this file when requesting /

RewriteEngine on
RewriteRule ^$ /demo.php [L]

Here we are using an empty regex pattern ^$ to match the root directory because ^/$ can not be used on htaccess context.


Redirect a specific directory and all its URLs to another directory

If you want to redirect a specific directory and all its URLs to a new directory , you can either use a simple Redirect or RewriteRule in your htaccess file.

Example with Redirect :

Redirect 301 /dir1/ /dir2/

Short an simple. This one liner redirect not only reditects your /dir/ to /dir2/ but it also preserves the path. So a request for /dir1/foobar will get 301 redirected to /dir2/foobar .

Example with RewriteRule

If the above Reditect doesn’t work then you may try the following RewriteRule based solution

RewriteEngine on
RewriteRule ^dir1/(.*)$ /dir2/$1 [R=301,L]


Serve subdomain from subfolder

If your subdomain is currently pointing to your document root folder and you want to point it to a subfolder instead, you can use RewriteRule directive for this.
You just need to create a rule with a condition that checks the host header. If the host header matches sub.domain.com then the rule will rewrite it to a folder named “sub” . The following is an example of that :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^sub\.domain\.com$ [NC]
RewriteRule .* /sub%{REQUEST_URI} [L]

Make sure to change the Domain name and folder name with your own in the code above.


Redirect all URLs to index.php

If you need to redirect all URLs to index.php then you can do this using the following rule in your htaccess file :

RewriteEngine on
RewriteRule !index\.php$ /index.php [L]

The code above silently forwards all URLs of your domain to index.php . If you want the redirection to be public and visible to browsers the you can replace the [L] with [R] for redirection


Deny access to a specific directory on Apache server using htaccess

If you want to protect a specific directory so that users can get a 403 forbidden error accessing it , you can use the following line in your htaccess

RedirectMatch 403 ^/folder/?$

This will return a forbidden error for example.com/folder/ .

You can also use RewriteRule to forbid a request for folder.

RewriteEngine on
RewriteRule ^folder/?$ - [F]

If your htaccess is in the folder that you are going to forbid , change RewriteRule’s pattern from ^folder/?$ to ^$ .

Using ErrorDocument in htaccess

ErrorDocument directive is used to handle different types of server errors. With ErrorDocument you can redirect specific error requests to your custom page. An example of 404 error is the following :

ErrorDocument 404 /404.php

With this code you can redirect your not-found site URLs to your custom page /404.php .


I hope these htaccess code snippets were helpful . Thanks so much for reading this post.

Categories
Apache mod-rewrite and htaccess related Articles

How to use Apache Files and FilesMatch directives in htaccess

Apache files and FilesMatch directives
In this article I will show you how we can use files and filesMatch directives in an htaccess file.

What is files directive and how to use it

Files directive is part of Apache core module . You can use this directive in an htaccess or server configuration file to apply other directive to one specific file or files inside files directive.
This directive works like a condition . You can use RewriteRule or Redirect directives inside files block so that the rule can apply to one specific file.

Code examples of files directive

You can use RewriteRule inside files directive something like the following :

<files "demo.php">
RewriteEngine on
RewriteRule .+ - [F,L]
</files>

The rule above rewrites a request to 403 forbidden page . As you can we have used a catch-all pattern in the rule but this will only apply to a specific file demo.php .

You can deny access to a specific file use deny directive something like the following :

<files "demo.php">
Deny from all
</files>

The code above denies access to a specific file named demo.php .
If you want to use a regular expression based match in files then you need to use a ~ character.

<files ~ ".+\.php$">
deny from all
</files>

The code above searches for all PHP files a denies the access.

How to use FilesMatch directive in htaccess

FilesMatch directive is same as Files except for one thing. FilesMatch uses a regular expression based pattern instead of static one. You can also use regex with files directive with a ~ char but in FilesMatch you can use a pure regex based pattern.

<filesMatch ".+\.html$">
ReditectMatch 404 .html
</FilesMatch>

The code above redirects all html files to 404 not-found error.

Categories
Apache mod-rewrite and htaccess related Articles

Add trailing slash to URLs using htaccess | Enforce URL trailing slash

Add trailing slash to URLs

This article is for Apache users who want to learn how to add a trailing slash to URLs.

A trailing slash is / character that appears at the end of URLs something like the following :
https://example.com/foo/bar/ .
In this article we will learn how to add a trailing slash to URLs using RewriteRule directive in an htaccess file.

How to add a trailing slash to URLs

One of the easiest and most convenient way to add or enforce trailing slashes on URLs is by RewriteRule directive.

You can write a single rule in your htaccess file that will apply to all URLs without a trailing slash.
You can use a 301 redirect rule in htaccess that can do the following :

Redirect 301
https://example.com/foobar
To
https://example.com/foobar/
Here is the Rule you can use to enforce a trailing slash :

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.+)$ /$1/ [L,R=301]

The rule doesn’t add a trailing slash to your files because you will not want have your file URLs to look something like /file.php/ that’s why the first condition is there to prevent that.
The second condition in the rule above checks URLs that do not end with / because we do not want to add a trailing slash to URLs that already have one.
If the both conditions are met then the RewriteRule is applied . The rule redirects all URLs without a trailing slash to include a slash at the end.

Is it important to include a trailing slash at the end of all URLs

If you think a URL with a trailing slash is going to win SEO then you are doing it the wrong way. A URL with trailing slash and the one without it is considered same from SEO point of view. You can think it like a domain with with www and a domain without www. It’s not going to make any difference . It’s just how you want your URLs to appear . A URL with a / at the end looks complete so it’s completely up to you what version of URLs you want to have for your website.

Related : How to remove trailing slash from URLs

Categories
Apache mod-rewrite and htaccess related Articles

How to match against root directory using RewriteRule in htaccess

htaccess match root directory

In this article I will show you how to match or rewrite root directory path using RewriteRule directive in an htaccess file.

How to match root directory

RewriteRule directive uses a relative path pattern in htaccess Context. You don’t need to use full path as RewriteRule already knows the current directory or the directory the htaccess is located in.
If your htaccess file is located in root folder then to match against the root directory that is / by default, you can use an empty regex pattern something like the following :

RewriteRule ^$ /demo.php [L]

The ^$ in the pattern above matches an empty URI so in the rule above it matches your root directory if the htaccess is located in root.
If your htaccess file is located in a subdirectory say /demo then to match against the subdirectory you will need to use exact same pattern

RewriteRule ^$ /demo.php [L]

The rule above in /demo/. htaccess matches the /demo/ directory . This will rewrite /demo/ to /demo.php .

Categories
Apache mod-rewrite and htaccess related Articles

How to redirect domain with exception using RewriteRule in htaccess

htaccess redirect domain with exception

Through this article we will learn how to write a code in htaccess to redirect a domain to another domain with exception.
We will use both directives
RewriteRule and
RedirectMatch in the example codes because both directives can be used in htaccess but you should always prefer RewriteRule as it’s faster then Redirect .

Redirect domain with exception using RedirectMatch

You can use RedirectMatch directive for URL redirection as its much similar to RewriteRule but you can’t redirect based on host header using this directive.
If you need to redirect your domain to another domain on different server , (for example : You have a domain name xyz.com and you want all traffic to this domain to route to a domain on remote host) then you can use RedirectMatch .

Ok , here in the first example we will use RedirectMatch to redirect our domain and all its pages to another domain but with an exception that our /page2 shouldn’t redirect.
We can use this in our htaccess :

RedirectMatch 301 !/page2 https://example.com

The code above redirects your site.com/foobar (excluding /page2) to your example.com/ .

If you also need to preserve the URL path , then first you need to capture it in the pattern using regex and then use the match with destination URL.

RedirectMatch 301 ^/(?!page.php).*)$ https://example.com/$1

Redirect domain to another domain with exception using RewriteRule

I always prefer RewriteRule directive for URL redirection and rewriting because its read quickly by Apache server.
If you have other directives in your htaccess then unlike RedirectMatch RewriteRule won’t get overridden but instead it will do what it does on its own.
RewriteRule and RedirectMatch are directives of two different Apache modules. The main difference between these two directives is the runtime behavior.
RewriteRule is always read first by server regardless of where its placed in htaccess.
With RewriteRule you can also Redirect your domain based on host headers.
This is helpful especially when you have multiple domains and you want to redirect a specific one.

Okay, here is how we can convert the above RedirectMatch into RewriteRule.

RewriteEngine on
RewriteRule !page1 https://example.com [L,R=301]

The rule above redirects all requests except /page1 from your domain to the homepage of example.com domain.

If you also need to preserve the URL path , then you can use the same pattern as we used with RedirectMatch above but trim the leading slash as its not used in RewriteRule on htaccess context :

RewriteEngine on
RewriteRule ^((?!page).*)$ https://example.com/$1 [L,R=301]

You can also use RewriteCond directive with RewriteRule to exclude the path . The code example above will look like the following with RewriteCondition :

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/page [NC]
RewriteRule .* https://example.com/$1 [L,R=301]

The RewriteCondition is there to exclude the specific page , so you can just use a catch-all pattern with your rule.

To exclude multiple URL paths you can use RewriteConditions with OR flag. The following is a code example to do that :

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/page [NC,OR]
RewriteCond %{REQUEST_URI} !^/page2 [NC]
RewriteRule .* https://example.com/$1 [L,R=301]

Related : Mod-rewrite and htaccess tutorial for beginners


I hope this article was helpful! Thanks for reading!