≡ Menu

Nginx Redirect Mobile / Smart Phone Traffic To Mobile Version Of the Web Site

I am a new nginx user and I would like to redirect all mobile / smart phone users from www.example.com to m.example.com domain. How do I detect a mobile phone browser in nginx? How do I redirect all mobile users to sub-domain using regex based rules? How can I automatically redirects visitors on mobile devices to its mobile version at http://m.example.com/ and also allow mobile devices to the desktop website at www.example.com if visiting via http://www.example.com/?desktop=true?

Tutorial details
DifficultyIntermediate (rss)
Root privilegesYes
Estimated completion time15 minute
You can easily redirect all mobile users using nginx as follows:

  1. m.example.com - Mobile domain name. Make sure app is configured to display same page as served on www.example.com
  2. All desktop clients need to use www.example.com. However, m.example.com i.e. all mobile phone user can browser desktop version if visiting via www.example.com/?desktop=true
  3. Make sure line Disallow: /*? added to /robots.txt on www.example.com
  4. /robots.txt - It is a good idea to block all bots on m.example.com. This ensures that mobile users will see lightweight page; but all bots refer to your main site. This is SEO feature. Sample /robots.txt for m.example.com
User-agent: *
Disallow: /

From the robots.org page:

The "User-agent: *" means this section applies to all robots. The "Disallow: /" tells the robot that it should not visit any pages on the site. Bad robots can ignore your /robots.txt. Especially malware robots that scan the web for security vulnerabilities, and email address harvesters used by spammers will pay no attention. However, good robots such as Googlebot will follow your /robots.txt file.

Sample /robots.txt for www.example.com:

User-agent: *
Disallow: /*?

Nginx configurations

Edit the nginx.conf file and append the following after server directive:

set $mobile_rewrite do_not_perform;
## chi http_user_agent for mobile / smart phones ##
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino") {
  set $mobile_rewrite perform;
if ($http_user_agent ~* "^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)") {
  set $mobile_rewrite perform;
## redirect to m.example.com ##
if ($mobile_rewrite = perform) {
  rewrite ^ http://m.example.com$request_uri? redirect;

Adding exceptions

You can allow user to browse and view desktop version of your site if url has www.example.com/?desktop=true. You can set cookie as follows:

set $force_dt_cookie  "";
if ($args ~ 'desktop=true') {
  set $mobile_rewrite do_not_perform;
  set $force_dt_cookie  "desktop=true";
add_header Set-Cookie $force_dt_cookie;
if ($http_cookie ~ 'desktop=true') {
  set $mobile_rewrite do_not_perform;

Save and close the file. Restart or reload the nginx server, enter:
# /usr/sbin/nginx -s reload
# /etc/init.d/nginx reload

Test it

Use the curl command as follows to see redirection:

curl -I -A "UserAgentString" http://www.example.com
curl -I -A "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3" http://www.example.com
curl -I -A "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3" 'http://www.example.com/?desktop=true'
Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 5 comments… add one }

  • Latheesan August 5, 2013, 10:20 am

    Awesome article! Been looking for a smart way to do this at web server level, rather than web site level. Now this will make my mobile dev easier :)

  • David December 13, 2013, 3:27 pm

    Just one quick comment. Google recommends that you allow them to spider both desktop and mobile versions of the site so that they can index both. Instead of excluding the m. site you should add in a canonical link element to the mobile version and add a rel=”alternate” tag to the desktop site. This will let Google (and other SEs) that the pages are the same.


  • Guzmán Brasó June 6, 2014, 1:13 am

    Regexp it’s outdated, most common mobile phones UA of today does not match, for example most androids does not include the word “mobile” in the UA so it fails to match.

    Would love to see an updated version

  • maone April 25, 2015, 12:23 am

    Hi, seems you forgot to put IPad out there, yours is just ip(hone|od). It would be great if you use this one instead ip(hone|od|ad).

    Anyway thanks for your great Nginx tutorial, you saved my ‘life’,

Leave a Comment