19

I'm looking to do some mobile-specific layouts in my app, and have been researching ways to detect mobile browsers and serve mobile specific layouts.

I came across this: http://www.arctickiwi.com/blog/mobile-enable-your-ruby-on-rails-site-for-small-screens

But using an array of keywords seems a little fragile to me. What if the keywords change? Anyone come across any gems or plugins or any more future proof strategies?

Slick23
  • 5,827
  • 10
  • 41
  • 72

3 Answers3

28

The best way is to use some supported plugin/gem, like browser You're just unable to follow all browsers with their custom user_agents. For example Opera 11.50 has the following user_agent:

Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/ADR-1111021303; U; en-GB) Presto/2.9.201 Version/11.50

It is totally unrecognizable with

request.user_agent =~ /Mobile|webOS/ 
Amit Joki
  • 58,320
  • 7
  • 77
  • 95
gshilin
  • 647
  • 14
  • 23
  • 1
    +1 to not reinventing the wheel. `mobile-fu` seems unmaintained, but at time of writing the `browser` gem is and does the job: https://github.com/fnando/browser (edit: SO saving when I press return) – mezis Feb 23 '15 at 09:00
20

There is actually a much simpler regular expression you can use. The approach is outlined in this Railscast and allows you to load different JS and define different page interactions for mobile devices.

Essentially you end up with a function that simply checks that the user-agent contains 'Mobile' or 'webOS':

def mobile_device?
  if session[:mobile_param]
    session[:mobile_param] == "1"
  else
    request.user_agent =~ /Mobile|webOS/
  end
end
Pan Thomakos
  • 34,082
  • 9
  • 88
  • 85
  • 1
    Won't the first condition of the `if` statement always evaluate to `nil`? It looks as though the answer was pasted from [here](http://railscasts.com/episodes/199-mobile-devices?view=asciicast), but it left out the bit that would sometimes cause `session[:mobile_param]` to be non-`nil`. – Patrick Brinich-Langlois Oct 07 '15 at 00:13
  • Also, if you want to use a regular expression for this, you'd probably be better off with one from http://detectmobilebrowsers.com/. – Patrick Brinich-Langlois Oct 07 '15 at 00:14
  • Perhaps worth to add "Android": `request.user_agent =~ /Mobile|webOS|Android/` – blackchestnut Jul 26 '16 at 05:02
  • @PatrickBrinich-Langlois is correct here: the above code snippet will **not** work unless the rest of the code from the RailsCast is also implemented. Without it, `session[:mobile_param]` has no meaning. – jayp Jan 08 '17 at 01:21
4

Consider going away from the actual rails app on this one, and just change the css which is styling your page, that way you only have to rewrite the style sheet

Basically the css can detect when the page width is small (ie mobile browser) like this

<link rel="stylesheet" href="handheld.css" 
media="only screen and (max-device width:480px)"/>

and you can use this to have two different css handheld.css and normal.css for instance

Resources

Where I got that code snippet

and the article that article references

Paul Kaplan
  • 2,885
  • 21
  • 25
  • 3
    I really need mobile specific methods on this, not just layouts, so a pure CSS approach won't work. – Slick23 Jun 02 '11 at 20:36