Fri. Feb 26th, 2021

Mobile redirect dengan Nginx server

Dicopas sepenuhnya dari  😀

Using Nginx for redirection

Visitors should not have to go to the Rails app just to be redirected away from it. By having the logic in Nginx, we can reduce unnecessary request to the Rails app and also reuse the implementation for other projects that might be built with Node.js, Python, static HTML, or something else.

Defining the flow

The logic that most websites use for desktop / mobile redirection:

  • Mobile devices visiting should redirect to
  • Desktop clients should continue to
  • Mobile devices should be allowed to the desktop website if visiting through
  • A cookie should be set when a mobile device chooses the desktop version to remember the choice.

Redirecting to mobile website

To start, here is a very basic Nginx server configuration that can serve static pages.

server {
  listen 80 default deferred;
  root /home/example/app/example_app/public;

  location / {
    index index.html;


The redirection logic is actually quite simple, but one gotcha is that if blocks in Nginx can be unpredictable. There is even an article on the Nginx Wiki about the evils of if.

Because of this, if blocks are kept out of a location context and only used for setting variables, with one exception being the actual redirection.

set $mobile_request false;

if ($http_user_agent ~* '(Mobile|WebOS)') {
  set $mobile_request true;

if ($mobile_request = true) {
  rewrite ^$request_uri? redirect;


The $mobile_request variable is initialized as false, then is set to true if the requesting browser is a mobile device. Finally, if the $mobile_request variable is true, a redirect happens.

Setting a cookie, checking a cookie

Cookie creation should be handled in Nginx, too, but I had some initial issues since add_header cannot be inside an if block in the server context (though it can in the location context).

Because of the add_header restriction, the $mobile_cookie variable needs to be initialized before the if block that could set it to false, because add_header Set-Cookie is always going to be used.

set $mobile_cookie  "";

if ($args ~ 'mobile=false') {
  set $mobile_request false;
  set $mobile_cookie  "mobile=false";

add_header Set-Cookie $mobile_cookie;

if ($http_cookie ~ 'mobile=false') {
  set $mobile_request false;


Exceptions to the redirection

One major issue that can come up from this implementation is the mobile check happens on every HTTP request through Nginx. This is not a problem for our company website since assets are hosted on Amazon S3, but if your hosting assets at /assets/ or elsewhere, you’ll need to add exceptions to treat all request to that directory or file as non-mobile.

if ($uri ~ /assets/) {
  set $mobile_request false;


All together

Because of the $request_uri in the redirection block, the code assumes the routes of your desktop website and mobile website will be the same, or at least mapped accordingly on the mobile side of the implementation, but that’s another post.