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
Requirementsnginx
Time15 minute
You can easily redirect all mobile users using nginx as follows:

ADVERTISEMENTS

  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;
  break;
}

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
OR
# /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'
References
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNCentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
10 comments… add one
  • Latheesan Aug 5, 2013 @ 10:20

    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 Dec 13, 2013 @ 15:27

    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.

    Cheers
    Dave

  • Guzmán Brasó Jun 6, 2014 @ 1:13

    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 Apr 25, 2015 @ 0:23

    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’,

  • hax0r May 18, 2016 @ 1:18

    this config too many redirect

  • Hardik Patel May 18, 2016 @ 10:51

    I would like to suggest a change in 1st regex. So it can identify ipads too.

    Changed regex:
    android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|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

  • Luis muzquiz Sep 17, 2016 @ 16:36

    Nginx docimentation says using if on vhosts is evil.

  • Dana Johnson Feb 5, 2017 @ 18:14

    can you please show the full config ?

    as which one comes first and which one comes later in config ?

    i would like to add exception too. so that mobile users who wants to use desktop site can do so.
    thanks

    thanks

  • Azfar Sep 10, 2017 @ 13:07

    I want to run both desktop and mobile domains on same doamin and my mobile app is on angular. How can I achieve it?

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.