Categories
apache Apache mod-rewrite and htaccess related Articles htaccess

Apache .htaccess tutorial for beginners | Learn URL rewriting and basics of mod_rewrite – helponnet.com

htaccess has always been a confusing topic for all Apache users especially for newbies who are learning to write RewriteRules to modify URLs via an htaccess file. The reason why some people find it confusing is because the Apache mod-rewrite documentation is hard to follow and there are no easy to follow htaccess step by step tutorial available on the internet.
I often see users struggling with their RewriteRule code on StackOverflow and I help them fix issues when I can.

In this 10 minute read article I am going to post an htaccess short step by step tutorial for people who wish to learn some basics of URL rewriting on Apache server.
If you follow this tutorial from top to the bottom then I am sure you will learn alot about URL rewriting and you will have some basic idea to create your own RewriteRules.


What is an .htaccess file?

What is an htaccess file

It’s a directory level configuration file used by Apache web server to modify URLs , directory appearance and other server settings.

.htaccess is a dot prefix file.
The name starts with a single dot . and ends with htaccess .

You can change the name to make it look something like htaccess.txt from your server.config file.
The benefit of using an htaccess file is that it’s easy to edit and available on all types of hosting services.

The downside of using an .htaccess file is that it slows down your server performance as it’s read on each request but that’s not going to be a big issue for you.
You can see the world’s largest CMS WordPress also uses an htaccess file to shorten the blog URLs.
An htaccess file is easy to maintain and set-up that’s why many web developers prefer to use it rather then editing the main configuration file.

Apache mod-rewrite

Rewrite module aka mod-rewrite is a powerful Apache module that provides URLs rewriting functionalitis to Apache users.
The official documentation of mod_rewrite is available on Apache mod_rewrite.
Mod-rewrite provides URL rewriting directives such as

RewriteEngine
RewriteBase
RewriteRule
RewriteCond
All these directives are used in an htaccess file to manipulate incoming URL requests and other settings on the server.

You will learn more about these directives later in this article but for now just focus on what the Rewrite module is and how to enable it.
Almost all live web hosting providers will provide you Apache server with pre-installed mod-rewrite. But in some rearest cases if it’s not already installed then you can ask your service provider to enable it for you or you can also enable it yourself by modifying the server configuration file that’s located in /etc/httpd/conf/httpd.conf .
Open this file for editing and replace the line AllowOverride none to AllowOverride all this will then make it possible to use mod-rewrite in an htaccess file.

To verify whether your server supports mod-rewrite in htaccess , you can do the following :

  • Create an .htaccess in your public_html folder.
  • Put some random texts to your htaccess file like “fooooobarrr” .
  • Now, visit any URL on your site.

If it generates a 500 internal server error then the mod-rewrite is enabled on your server otherwise if you don’t get any error then you will need to enable this using the easy method I mentioned above.

Let’s create our first Hello-world RewriteRule

If you are learning to write htaccess rules while following this article , then I suggest you start learning with an empty htaccess file as with an empty Htaccess you can delete the code if something goes wrong or you want to test a different code, this will improve your learning experience.

Create an htaccess file on your document root and put the following contents in that file :

RewriteEngine on
RewriteRule ^helloWorld$ /index.php

Save the htaccess file and type the following URL into your browser address bar :
https://yourdomain.com/helloWorld
You will see the real rewrite mazic happening now.
The rule will internally map your URL path /helloWorld to the destination file /index.php.
The redirection happens behind the screen. You will see contents of the index.php file on the /helloWorld path.

Congratulations , you have written your first helloWorld rule successfully.
Now let’s understand how the code above works. Let’s understand it line by line.

  • RewriteEngine on : This directive turns on the engine for rewriting URLs.
    This directive should be placed once at the top of your htaccess.
    There is no need to add “RewriteEngine” with each rule, just one single line at the top is enough.
  • RewriteRule ^helloWorld$ /index.php : This is a RewriteRule directive provided by mod-rewrite. This line rewrites the request from /helloWorld to /index.php .
    You might have noticed one thing that our Rule’s pattern doesn’t start with a leading slash / .
    This is because RewriteRule uses a relative path in its pattern so ^/helloWorld$ will not work in htaccess but in a server.config file.

Okay, now I hope you have had some basic idea about how to create a simpe RewriteRule.
Now we will learn about other parts of a RewriteRule.

Mod-rewrite Flags

Flags are optional in RewriteRule but you will need to use them in most cases.
Flags provide additional instructions to a RewriteRule.
For example a RewriteRule with [R] flag tells the rule to make an external redirection of URLs.

See a list of most commonly used flags in mod-rewrite .

Flags are used inside sequere brackets [] .
You can use multiple flags with a RewriteRule seperating them by a comma char ,.

Flags are optional in RewriteRule but you will most often need to use them in Rule to change the URL rewriting behaviour.

You will needv to use [NC] flag in the following Rule:

RewriteRule ^foobar$ /index.php

NC stands for NoCase, this flag is used to match both uppercase and lowercase chars in URI.
With NC, the rule above will match the following both URIs :


/foobar

and
/fOObAr
otherwise without this flag, by default RewriteRule only matches the case sensitive URI string.

You can learn more about flags on this post .

Conditions in RewriteRule

Conditions in Apache mod-rewrite

You can use conditions with your RewriteRule to rewrite or redirect your site URLs based on some specific conditions.

RewriteCond directive is used for this purpose.
With RewriteCond you can rewrite your URL based on host , https , request URI headers.

Check this post to learn more about using RewriteCond directive.
You can use if/else logic for RewriteRule .

The following Rule uses RewriteCond to redirect the URL based on host header. The condition used in this rule can also be read as
“If host ==example.com then Redirect .

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^foobar$ /index.php [R]

This rule will redirect /foobar to /index.php if the condition is met.

You can use multiple conditions with a single RewriteRule .

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^foobar$ /index.php [R]

The conditions above uses [OR] flag. This makes one of the conditions optional. So you can read it as :
“If host ==example.com OR host==www.example.com” then Redirect.

To redirect http URLs to https , you need a condition logic. That checks if the incoming URL is using http scheme , then redirect the URL to use https :

RewriteEngine on

RewriteCond %{REQUEST_SCHEME} ^http$
RewriteRule (.*) https://example.com/$1 [R]

I hope now you have had some basic idea of how conditions work and how to use them with RewriteRule.

Regex in mod-rewrite

RewriteRule regex

Mod-rewrite directives RewriteRule and RewriteCond use a regular expression based pattern that makes the match easier.
With a Regex based pattern a single RewriteRule can match multiple URIs.

If you want to learn Regex , you can follow this tutorial .

The following rule with regex pattern can either match /helloWorld or /hello ladies :

RewriteEngine on
RewriteRule ^(helloWorld|hello ladies)$ /index.php

The match is saved in $n variable . Since we have one capture group in the rule above , the match is saved in $1 .

You can use the matched value in the destination string of RewriteRule.

RewriteEngine on
RewriteRule ^(helloWorld|hello ladies)$ /index.php?q=$1

The rule above rewrites /helloWorld to /index.php?q=helloWorld

You can use Regular expressions with RewriteCond :

RewriteCond %{HTTP_HOST} ^(www\.)example.com$

The condition above checks both www and non-www domain .

Isn’t it easier with Regex?

Comments in htaccess code

In any programming languages , comments are used to explain the block of code. Like in PHP we use # to write a single line comment and /*…*/ for multiple lines.
In htaccess , you can only comment out a single line using the hash character # .

Anything that goes after # is treated as a comment in htaccess.

#This is a comment.
#This is another comment.

To explain an htaccess code you can start your comment with a # character but keep in mind that the # is a single line comment. To add multiple line comments you will need to start each line with a hash character like the example shown below

#redirect http to https
#This rule also reditects non-www to www at the same time
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www
RewriteRule (.*) https://www.example.com/$1 [L,R]

Error handling with htaccess

With an htaccess file you can handle server errors with just a few lines of code.
On Apache there are different types of server errors . Some most common errors are :

  • 403 (Forbidden error)
  • 404 (Not found error)
  • 410 (Gone)
  • 500 (Internal server error)
  • 503 (Server unavailable) .

With an htaccess file you can easily handle these server errors using ErrorDocument directive which is part of Apache core module.
403 is the error status code which represents a “Forbidden error” (Access to the resource is denied) .
To redirect your site URLs to a different location when this error occurs, you can use the following code in htaccess :

ErrorDocument 403 /403.php

Here 403.php is the file that is called when you request something that is protected on your server.

The code below handles 404 “not found” URLs.

ErrorDocument 404 /404.php

The same code format is used to handle other server errors except 500 (Internal server error) . You need to handle it from your main server configuration file.

RewriteRule code examples

WWW to non-www

With the following rule you can redirect your www subdomain to root domain :

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

Redirect non-www to www (naked domain to www subdomain)

If you want to redirect your root domain to www subdomain , here is the rule you can use to enforce www on your website :

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

Change directory index file

By default , your server shows index.html , index.php or whatever index file exists to client when a directory is direct accessed , but you can change this behaviour by simply using the following line in htaccess , read more about DirectoryIndex

DirectoryIndex somefile.php

Access all files without adding an extension at the end

If you need visit your file URLs without adding extension at the end , for example : to visit /file.php as /file you can use the short code below in your htaccess :

Options +Multiviews

Enforce SSL

You can redirect your insecure traffic (http) to the secure version (https) using this rule :

RewriteEngine on
RewriteCond %{HTTPS} off [NC]
RewriteRule (.*) https://example.com/$1 [R=301,L]

Add a trailing slash

To add a trailing slash to your URLs , you can use the following :

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !/$ %{REQUEST_URI}/ [R,L]

Allow non-php extension

If you want to access your .PHP files without using extension at the end , you can use :

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

More rules : 5 Awasome htaccess rules you can just copy & paste .

.htaccess tutorial pdf

This htaccess tutorial is available for download as PDF format. You can Download this htaccess tutorial as .pdf and use it for personal and educational purposes only.

I hope this tutorial was helpful. If there is anything that you couldn’t understand or you need my help with htaccess , you can post a comment bellow.

Thank you so much reading this.

Categories
apache Apache mod-rewrite and htaccess related Articles htaccess

How to set an ENV (Environment) variable using RewriteRule in htaccess

Setting environment variables by htaccess

There are different ways and directives to set an environment variable on Apache server through a htaccess file. One of the most common and the easiest way to set an Environment variable is by using a RewriteRule directive. It’s the easiest method because you can rewrite your domain requests based on env and also you don’t need to write multiple lines of code a one single line of Rule can do this for you.
In this article I will show you how can set the ENV variable using our htaccess file. I will post some code examples to explain the process.

Setting an ENV via mod-rewrite

You can use the mod-rewrite E flag which is short for ENV to set the variable on your server.
The following RewriteRule example sets an ENV variable named foo value bar :

RewriteEngine on

RewriteRule .* - [E:foo=bar]

The rule above will set the ENV foo and assign bar as value to it. The pattern .* matches all URLs meaning that if you visit any URL of your site the ENV will be set. You can change or restrict the pattern to match a specific path only if you want to.
For example the pattern ^demo.php$ will set the ENV only if the /demo.php is requested.

How to check the ENV variable

To check if the variable is set or notset you can match against %{ENV:varName} in a RewriteCond.
The following example checks if the variable “foo” is set and contains bar as value.

    RewriteCond %{ENV:foo} ^bar$

To set the variable if its not already set you can use a RewriteRule

RewriteEngine on

RewriteCond %{ENV:foo} ^$
RewriteRule .* - [E:foo=bar]

The ^$ in condition pattern above checkeks an empty string. If the foo variable is empty/notSer then the rule is triggered and sets the ENV variable.

Setting ENV using mod-env

Apache ENV module provides three different directives to set an environment variable in htaccess and server configuration file.

  • SetEnv directive
  • SetEnvIf directive
  • SetEnvNoCase directive
  • These three directives can be used to set the ENV variable if you don’t want to use a RewriteRule based solution.
    SeEnv directive takes two perameters env_name and env_val .
    The following example sets an environment variable named “foo” and value “bar” :

    SetEnv foo bar
    

    You can use SetEnvIf directive to set the variable conditionally based on requested URIs and Host headers, for example, If you need to set ENV variable only when the request is for /file.php , you can use the following :

    SetEnvIf request_uri ^/file.php$ foo=bar
    

    SetEnvNoCase is same as the SetEnvIf except that it ignores the case of characters in pattern, this also matches a request URI string with uppercase characters ie : /FiLe.php .

    SetEnvIfNocase request_uri ^/file.php$ foo=bar
    
Categories
apache htaccess url-redirection

http to https and enforce www in one 301 redirect on htaccess

Htaccess redirect http to https non www to www
If you are looking for an htaccess RewriteRule that enforces www and https in one redirection and without creating multiple redirects then you have come to the right place. On this article I am going post a 100 percent working rule that you can just copy and paste to your htaccess file.

Here is the RewriteRule :


RewriteEngine on

RewriteCond %{HTTP_HOST} ^example.com$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.example.com/$1 [NC,L,R=301]

How to use the code : You can just copy and paste it to your htaccess. Since this redirects all non-www and non-https URLs to https://www this is the main rule and should be placed at the top of your htaccess file.
What needs to be changed : You need to change the domain name to your domain. Replace example.com with yourdomain.com in the code and test the rule , if it works then change R to R=301 in the flag section to make the redirection permanent and browser cache-able.

http to https multiple domains

If you are looking for a rule the redirection dynamically, and you don’t want to change hostname manually, then the following one should fullfill your need as it can redirect multiple domains


RewriteEngine on

RewriteCond %{HTTP_HOST} !^www. [NC,OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$
RewriteRule ^(.*)$ https://www.%1/$1 [NC,L,R=301]

The rule above applies to multiple domains at the same time. You don’t need need to change anything in the rule as it automatically detects host and https headers.

RewriteRule for Cloudflare users

If your domain is on cloudflare then the rules I posted above might fail to work as Cloudflare doesn’t recognise %{HTTPS} variable. Cloudflare has its own variable to test URL scheme. RewriteEngine on RewriteCond %{HTTP:CF-Visitor} ‘”scheme”:”http”‘ is the variable Cloudflare uses to detect URL scheme.
So in that case, you can you can use the following RewriteRule :


RewriteEngine on
RewriteCond %{HTTP_HOST} !^www. [NC,OR]
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteCond %{HTTP_HOST} ^(?:www.)?(.+)$
RewriteRule ^(.*)$ https://www.%1/$1 [L,R]

Categories
apache Apache mod-rewrite and htaccess related Articles htaccess

Mod-rewrite NE flag uses and code examples

NE flag htaccess
In this article we will learn about mod-rewrite NEflag. What this flag is used for and why we should use it all these frequently asked questions are answered in this article.
NE stands for NoEscape
We use this flag in RewriteRule to tell the engine not to escape special characters like # , & .. in URLs.

Here is an example of how mod-rewrite works without NE flag :

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

The rule above will redirect /foobar to https://example.com/%23foobar
As you can see the redirected URL path has changed to %23foobar . The # changed to its hexadecimal value%23 .This is because the rewrite engine converts special characters in redirected URL to their hex code. The characters are escaped by default if NE flag is not present in RewriteRule.
RewriteRule example with NE :

RewriteEngine on
RewriteRule ^foobar$ https://example.com/#foobar [NE,L,R]

The rule above does the redirection of the URL perfectly fine. This doesn’t change # to %23 as we used NE flag that tells server not to do so.

Categories
apache Apache mod-rewrite and htaccess related Articles htaccess url-redirection

5 awesome htaccess rules you can just copy and paste

htaccess copy & paste rules

In this post you will find 5 mod-rewrite rules that you can just copy and paste to your htaccess file.

htaccess copy paste rules with code examples.
All the rules provided here are tested and works perfectly fine in an htaccess file. If you are one of those guys who loves to copy and paste code , then this post is for you. I have provided 5 RewriteRules here that you will need most often in an htaccess file.

Table of contents

  1. WWW domain to non-www
  2. Non-www domain to WWW
  3. http URLs to https
  4. Remove php extension
  5. Disable image hotlinking
  6. Mod-rewrite custom error document

Www to non-www redirection rule

If your domain is available with two versions www and www then it’s important that you either redirect your non-www to www or the www version to non-www . If you don’t do this and your domain has two different URLs pointing to the same location , it can impact your SEO. So here you have two choices :
Non-www domain to www :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain.com$ [NC]
RewriteRule ^.*$ https://www.domain.com%{REQUEST_URI} [NC,L,R]

or www domain to non-www :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.com$ [NC]
RewriteRule ^.*$ https://domain.com%{REQUEST_URI} [NC,L,R]

You can use one the rules provided above to either redirect to non-www or www. Just copy the rule above and paste it to your htaccess file. Remember to put this at the top of your htaccess file otherwise your other rules may override it.

SSL redirection rule

You need this rule to redirect your httpURLs to https . After enabling SSL certificate on your website, your next step is redirect your site visitors to a secure connection if they try to visit your site using http scheme.
So here is the rule you can use for this type of URL redirection.

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://www.yoursite.com%{REQUEST_URI} [NC,L,R]

The rule will not work if you are behind a proxy server or you are using Cloud flare because Cloudflare uses a different variable to detect ssl, if your site is on cloudflare , then you can use the following instead :

RewriteEngine on
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
RewriteRule ^ https://exemple.com%{REQUEST_URI} [NE,R,L]

Remove .php extension from URLs

To make your php URLs clean and shorter you can remove their extension. Here is the rule you need to remove .php extension from your URLs :

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

To remove any other file extensions , you can just replace the php with your extension in the code above.

Disable hotlinking of image files

If other websites or external sources are using your site images then its important that you take some actions against them . Hotlinking of image files consumes your server bandwidth and resources. The quick action you can take to disable hotlinking of image files is an htaccess rule that will check the http referer . If referer is not your own domain then forbid the image requests.
You can use the following htaccess code to achieve this :

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?(www.)?yoursite.com [NC]
RewriteRule (jpg|gif|png)$ - [F]

The rule above checks the referer string , if it doesn’t match the pattern , then a request for images ending with .png , .gif, .jpg gets a forbidden error. This can help save your server resources like the uses of bandwidth.

A custom error document with RewriteRule

Its really simple to create your own custom error document with RewriteRule. If you do not want your 404 requests to go to a default 404 page you can implement your own 404 error handler. For this create a php in your directory . Name it as 404.php this file will be used to serve 404 requests on your server.
And then add the following rule to your htaccess file :

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.+$ /404.php [L]

The rule will serve 404.php file for all non-existent requests. If you are using WordPress rules then this might not work as WordPress has its own RewriteRule that forwards all requests to a single page.

Categories
apache Apache mod-rewrite and htaccess related Articles htaccess url-redirection

Mod rewrite QSD flag and its uses in htaccess

htaccess remove query string from URLs

QSD stands for “Query String Discard” as the name implies this flag is used to discard query string from URLs. This flag is supported on Apache versions 2.4+ . If you use this flag on earlier versions the you will get an “internal server error” as the flag is not defined on earlier versions of Apache. Read how to trim queryString on older versions .
We use this flag to remove query strings from URLs when we want a clean redirected URL.

Examples of QSD flag

Suppose you have a URL that looks something similar to


https://example.com/file.php?q=foo&n=bar


And want to convert this URL into a clean format that doesn’t contain query string parameters , something like the following URL :


https://example.com/file.php


To achieve this, we can use a RewriteRule with QSD flag that can redirect our old URL to the new one (from queryString to without queryString) .
We can use the following RewriteRule in our htaccess file to remove queryString : RewriteEngine on
RewriteCond %{QUERY_STRING} ^q=foo&n=bar$
RewriteRule ^file.php$ /file.php [L,R,QSD]
Okay. So what the rule above does is it checks if the request is for “/file.php?q=foo&n=bar” if the condition is met then the rule redirects the URL to remove the queryString.

Categories
apache htaccess

How to use ErrorDocument directive in htaccess file? Apache URL Rewriting tips

ErrorDocument directive

ErrorDocument directive is part of Apache core module . To use this directive in htaccess you do not need to do anything . This directive is enabled on Apache server by default.

ErrorDocument can be used in htaccess or server.config file on Apache server.

We use this to manipulate broken or blocked URLs on Apache.

ErrorDocument directive is used to add a custom URL or parh so that the server can redirect you to this path (the URL path or URL you set as destination in ErrorDocument) when you request a broken URL.

Table of contents

Uses of ErrorDocument

ErrorDocument is most often used to manipulate not-found 404 URLs. You can use this directive to set your own custom page to handle 404 URIs on your website.

ErrorDocument syntex

This directive uses two required arguments error code and destination :


ErrorDocument errorStatusCode destination

You can use any HTTP error status code starting from 4XX to 5XX ie: 403.

You can use URL path , full URL or Text as the destination string .


ErrorDocument 404 /error.php

ErrorDocument document is a one liner directive and both arguments should be in a single line otherwise you will get a 500 invalid syntex error if line break is found.

Use ErrorDocument to redirect 404 URLs to a custom path

If you want to set your custom own path for broken URLs on your server , you can the following:


ErrorDocument 404 /error.php

The above line tells server to serve error.php file when a not-found URI is requested.

Your server will internally map the requested URI to /error.php meaning that the typed URL won’t change in browser address bar.

ErrorDocument directive internally maps the request if you use a absolute URL path as its destination .
If you use a full URL starting with URL scheme then the directive will perform an external redirection changing the browser URL.


ErrorDocument 404 http://example.com/error.php

The above example will redirect your 404 URLs to http://example.com/error.php making the redirection visible to browser.

Use ErrorDocument to print a custom error text

With ErrorDocument directive it is also possible to show a custom error response text on the same page .
You can replace destination path with your “custom error text” .

See the following example:


ErrorDocument 404 "Oh.. thats a 404 error"

This will show a custom error text on the requested not-found page.

The text string must be enclosed with .

You can also use html tags to format your custom text.



ErrorDocument 404 "<h1>Oh.. thats a 404</h1>"

Use mod-rewite variables with ErrorDocument

mod-rewite (url rewriting ) variables like %{REQUEST_URI} can be used in the destination string of ErrorDocument .
This will help you track your broken pages.
Here is how you can use server variables with ErrorDocument

ErrorDocument 404 /error.php?page=%{REQUEST_URI}

This will rewrite a broken URI to error.php you can get the requested broken URI on your error.php page using the following code

<?php
echo $_GET["page"];
?>

Please keep in mind that the above example will only work on Apache 2.4 or later versions . On earlier versions you will get the variables as is in your output.

Control 403 errors using ErrorDocument

You can use ErrorDocument to add custom error handler page for 403 errors on your site


ErrorDocument 403 /thispage.php

This will map all 403 forbidden requests to /thispage.php

ErrorDocument vs RewriteRule

RewriteRule directive takes precedence over ErrorDocument. If you have a RewriteRule that rewrites not-found requests to a specific file then your ErrorDocument won’t get triggered.

Let’s see an example:


ErrorDocument 404 /error.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /error.php [L]

Both directives above handles a 404 request but unfortunately the ErrorDocument line isn’t read by server even if it at the top this is because RewriteRule runs before ErrorDocument on Apache server.

The simple workaround to overcome this type of problem is either use ErrorDocument or a RewriteRule to handle 404 URLs.


References:

Categories
apache htaccess

Conditional URL rewriting on Apache server

In this post we will learn about conditional URL rewriting on Apache server. This conditional URL rewriting tutorial is for mod rewrite beginners and advanced users who wish to learn how conditions work and how they are applied to
RewriteRule .

If you follow this short tutorial from top to the bottom then you will get a basic->advanced and complete reference about the conditional rewriting.

I wrote this post on a special request from one of my blog readers .
I hope you will enjoy reading it.

Conditions in RewriteRule (RewriteConds)

We use RewriteRule directive on Apache server to rewrite URLs .

Sometimes when we want to conditionally rewrite our URLs we use RewriteCond a condition directive along with RewriteRule to do the logical rewriting.
Whenever you open an .htaccess file to see its contents you often see a line that looks something like “RewriteCond blala blabla [blabla]” followed by RewriteRule . Have you ever wondered why the line is there and what its used for? . Reading this tutorial from the top , now you might have understood what the RewriteCond is used for.
Now let’s see some real world conditional URL rewriting examples so that you can understand how it actually works .

RewriteRule without conditions

RewriteEngine on
RewriteRule (.*) https://example.com [R]

The RewriteRule above works. You can just copy and paste it to your htaccess file and then visit any URL .
So what does it do?
This rule redirects your website traffic to https://example.com . If you type any URL of your website, you will get redirected to the example.com domain .
Now suppose , you don’t want one of your site pages to redirect. Or you want to redirect all your site pages except one to example.com.
Do we need to apply some logic to the rule here?
Yes, definitely! This is where we need to use the “RewriteCond” directive.

RewriteRule with condition

Now we have the same but with a condition :
RewriteEngine on
RewriteCond %{REQUEST_URI} !/demo.php [NC]
RewriteRule (.*) https://example.com [R]
If you test this rule on your server , and type demo.php file you will see that the rule does not redirect this file but all other URLs are still redirecting to example.com . This is because we have added a RewriteCond that says
“If the request is for “demo.php” then do nothing. Else run the Rewriterule” .
This is how If/else logic is applied to RewriteRule .
In the next section Bellow we will learn about RewriteCond Syntex .

RewriteCond syntex

RewriteCond directive uses a simple set of syntex. It takes 3 parameters with third as optional parameters.

RewriteCond testString pattern flags
Flags parameter is optional while the two other are required.
Test string can be any server variable you want to check against the pattern ie %{HTTP_HOST} .
Condition pattern is the regex based pattern you can use to check the variable.
Flag you can use mod-rewrite flags like [NC] which is used to perform a case sensitive match . This parameter is optional .

How to use use Rewrite conditions with RewriteRule

You can use multiple RewriteConds with a RewriteRule. Just keep in mind that the conditions are applied to RewriteRule that immediately follows.
Consider the following examples :

RewriteEngine on
RewriteCond %{REQUEST_URI} !/demo.php [NC]
RewriteCond %{REQUEST_URI} !/demo2.php [NC]
RewriteRule (.*) https://example.com [R]
In the code above we use two conditions and both the conditions are applied to the rule. The conditions above work like AND logic . The rule trigger only if the both conditions are met.

  • Request_uri is Not “demo.php”
  • AND

  • Request_uri is Not “demo2.php”

If both conditions are met then server will trigger the rule to redirect all other requests to example.com .
You can use [OR] flag to change the condition logic to OR.
RewriteEngine on
RewriteCond %{REQUEST_URI} !/demo.php [NC,OR]
RewriteCond %{REQUEST_URI} !/demo2.php [NC]
RewriteRule (.*) https://example.com [R]
Now the condition logic has changed to OR. The rule will trigger only if either the request_uri is “/demo.php” or “/demo.php” .

You can find good mod-rewrite reference on the official Apache server webpage :
https://httpd.apache.org/docs/current/mod/mod_rewrite.html .
I hope this article was helpful and you enjoyed reading it.

Categories
apache Apache mod-rewrite and htaccess related Articles htaccess

How to set a different file as directory index using htaccess

With htaccess it is quite possible to change the directory index file to any other file. By default a file that contains the index perfix is served as directory index handler by the server. But this behavior can be changed by using a one line of code in htaccess.
In this post you will learn how to use a different file as directory index . This quick three minute read tutorial will teach you all about adding a custom index file on Apache server.
Whenever you create a new directory , you create an index file like index.html or index.php . An index file is important as it prevents directory listing otherwise if this file is missing then directory structure may be visible to clients. To prevent this from happening , we use an index file in a web directory.
Since an index file is served as directory handler by default, you can change the file to any other file by manually adding a directive in your htaccess file. There are two ways to do this , one is using the DirectoryIndex directive provided by directory module and the another one is using a RewriteRule to rewrite the directory to a file.

Using DirectoryIndex directive to change the index file

One of the easiest and recommend way to change a directory index file is DirectoryIndex a directive provided by mod-dir. You can use the the following line to achieve this behavior:


DirectoryIndex demo.html

This sets the demo.html file as directory index handler. Your server will show you the demo.html file content if you visit a directory even if the index.html is present in directory .

Using RewriteRule to change directory index file

You can also use RewriteRule directive to change the index file. For this you will need to rewrite your directory to the filename you want to be served as index.


RewriteEngine on

RewriteRule ^dirname/$ /demo.php [L]

For the root directory , you can use `^$` in the pattern as the root is treated as an empty URI in htaccess context.


RewriteEngine on

RewriteRule ^$ /demo.php [L]

Categories
apache htaccess

Remove .html and php extension with htaccess RewriteRule | URL Rewriting Tips

Remove php and html file extension from URLs using RewriteRule in htaccess

In this post we will learn how to use RewriteRule directive to remove html and php file extensions from URLs.

I know there are thousands of similar posts already indexed on the web but this post is unique and helpful to URL Rewriting beginners. I will provide you a 100% working code and you will learn to write your own code from the explanations.


Removing file extension from URLs is easy. You don’t need to be a URL rewriting expert to do that. With just two lines of RewriteRule code you can enable extension-less file requests on your server.
URLs without file extension look clean and preety. I personally use mod-rewite to hide file extensions from URLs because It makes my file URL short and easier to remember.

hide .html extension with htaccess

A basic rule that will allow you to visit html files without using .html extension at the end.

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

With the above rule you can access your file url as

http://example.com/file

Without typing the traling .html.

This rule doesn’t remove .html extension from URLs . It just makes it so that you can access your html file URLs without adding the extension at the end of the file name.
The rule rewrites your extension-less file requests to the orignal file location .Ie: /file will get rewritten to /file.php . The rewriting happens behind the scene and not visible to browser.

The drawback of using above rule is that it leaves you with two URLs pointing to the same location which can result in duplicate contents issues on search engines.
As I alrealdy mentioned, this rule doesn’t remove .html , using this simple rule you can access your html files either by going to /file or /file.php . Search engines can crawl both versions of your URLs .

To avoid this , you need to 301 redirect your .html URL to the new format ie: /file.html => /file . To permanently redirect your orignal URLs to the new format use a new rule. See the “complete rule to hide .html extension” bellow.

Remove .html extension from URLs (The complete rule)

Here is the complete rule that will remove html from URLs. You can use this in htaccess in /public_html folder .


RewriteEngine on
#1) redirect file.html to file
RewriteCond %{THE_REQUEST} /([^.]+).html [NC]
RewriteRule .+ /%1 [L,R=301]
#2) rewrite /file to file.html
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule (.*)/?$ /$1.html [L]

This rule will change your html file URL from

http://example.com/file.html

To

http://example.com/file

The rule will 301 redirect your html file URLs to its extension-less version taking care of the SEO rank of your domain URLs.

Remove .php extension from URLs (The complete rule)

If you need to remove .php from URLs, you can use the following RewriteRule in htaccess in your site root folder :


RewriteEngine on
#1) redirect file.php to file
RewriteCond %{THE_REQUEST} /([^.]+).php [NC]
RewriteRule .+ /%1 [L,R=301]
#2) rewrite /file to file.php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*)/?$ /$1.php [L]