{"id":13463491,"url":"https://github.com/fnando/browser","last_synced_at":"2025-05-13T16:03:42.888Z","repository":{"id":978629,"uuid":"779276","full_name":"fnando/browser","owner":"fnando","description":"Do some browser detection with Ruby. Includes ActionController integration.","archived":false,"fork":false,"pushed_at":"2024-12-04T18:30:40.000Z","size":953,"stargazers_count":2471,"open_issues_count":19,"forks_count":368,"subscribers_count":44,"default_branch":"main","last_synced_at":"2025-05-06T16:06:42.576Z","etag":null,"topics":["browser-detection","rails","ruby","user-agent"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fnando.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["fnando"],"custom":["https://paypal.me/nandovieira/🍕"]}},"created_at":"2010-07-16T17:25:01.000Z","updated_at":"2025-04-12T14:12:29.000Z","dependencies_parsed_at":"2024-04-30T17:48:25.063Z","dependency_job_id":"005e71b3-17ee-43d7-bead-873327e98d87","html_url":"https://github.com/fnando/browser","commit_stats":{"total_commits":531,"total_committers":109,"mean_commits":4.871559633027523,"dds":0.4896421845574388,"last_synced_commit":"a263513c4f35a79b8d359bf11043ff2da7bfe114"},"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnando%2Fbrowser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnando%2Fbrowser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnando%2Fbrowser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fnando%2Fbrowser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fnando","download_url":"https://codeload.github.com/fnando/browser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253411522,"owners_count":21904147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser-detection","rails","ruby","user-agent"],"created_at":"2024-07-31T13:00:54.312Z","updated_at":"2025-05-13T16:03:42.836Z","avatar_url":"https://github.com/fnando.png","language":"Ruby","readme":"# Browser\n\n[![Tests](https://github.com/fnando/browser/workflows/ruby-tests/badge.svg)](https://github.com/fnando/browser)\n[![Gem](https://img.shields.io/gem/v/browser.svg)](https://rubygems.org/gems/browser)\n[![Gem](https://img.shields.io/gem/dt/browser.svg)](https://rubygems.org/gems/browser)\n\nDo some browser detection with Ruby. Includes ActionController integration.\n\n## Installation\n\n```bash\ngem install browser\n```\n\n## Usage\n\n```ruby\nrequire \"browser\"\n\nbrowser = Browser.new(\"Some User Agent\", accept_language: \"en-us\")\n\n# General info\nbrowser.bot?\nbrowser.chrome?\nbrowser.chromium_based?\nbrowser.core_media?\nbrowser.duck_duck_go?\nbrowser.edge?                # Newest MS browser\nbrowser.electron?            # Electron Framework\nbrowser.firefox?\nbrowser.full_version\nbrowser.ie?\nbrowser.ie?(6)               # detect specific IE version\nbrowser.ie?([\"\u003e8\", \"\u003c10\"])   # detect specific IE (IE9).\nbrowser.known?               # has the browser been successfully detected?\nbrowser.unknown?             # the browser wasn't detected.\nbrowser.meta                 # an array with several attributes\nbrowser.name                 # readable browser name\nbrowser.nokia?\nbrowser.opera?\nbrowser.opera_mini?\nbrowser.phantom_js?\nbrowser.quicktime?\nbrowser.safari?\nbrowser.safari_webapp_mode?\nbrowser.samsung_browser?\nbrowser.to_s            # the meta info joined by space\nbrowser.uc_browser?\nbrowser.version         # major version number\nbrowser.webkit?\nbrowser.webkit_full_version\nbrowser.yandex?\nbrowser.wechat?\nbrowser.qq?\nbrowser.weibo?\nbrowser.sputnik?\nbrowser.sougou_browser?\nbrowser.epiphany?\n\n# Get bot info\nbrowser.bot.name\nbrowser.bot.search_engine?\nbrowser.bot?\nbrowser.bot.why? # shows which matcher detected this user agent as a bot.\nBrowser::Bot.why?(ua)\n\n# Get device info\nbrowser.device\nbrowser.device.id\nbrowser.device.name\nbrowser.device.unknown?\nbrowser.device.blackberry_playbook?\nbrowser.device.console?\nbrowser.device.ipad?\nbrowser.device.iphone?\nbrowser.device.ipod_touch?\nbrowser.device.kindle?\nbrowser.device.kindle_fire?\nbrowser.device.mobile?\nbrowser.device.nintendo?\nbrowser.device.playstation?\nbrowser.device.ps3?\nbrowser.device.ps4?\nbrowser.device.psp?\nbrowser.device.silk?\nbrowser.device.surface?\nbrowser.device.tablet?\nbrowser.device.tv?\nbrowser.device.vita?\nbrowser.device.wii?\nbrowser.device.wiiu?\nbrowser.device.samsung?\nbrowser.device.switch?\nbrowser.device.xbox?\nbrowser.device.xbox_360?\nbrowser.device.xbox_one?\n\n# Get platform info\nbrowser.platform\nbrowser.platform.id\nbrowser.platform.name\nbrowser.platform.version  # e.g. 9 (for iOS9)\nbrowser.platform.adobe_air?\nbrowser.platform.android?\nbrowser.platform.android?(4.2)   # detect Android Jelly Bean 4.2\nbrowser.platform.android_app?     # detect webview in an Android app\nbrowser.platform.android_webview? # alias for android_app?\nbrowser.platform.blackberry?\nbrowser.platform.blackberry?(10) # detect specific BlackBerry version\nbrowser.platform.chrome_os?\nbrowser.platform.firefox_os?\nbrowser.platform.ios?     # detect iOS\nbrowser.platform.ios?(9)  # detect specific iOS version\nbrowser.platform.ios_app?     # detect webview in an iOS app\nbrowser.platform.ios_webview? # alias for ios_app?\nbrowser.platform.linux?\nbrowser.platform.mac?\nbrowser.platform.unknown?\nbrowser.platform.windows10?\nbrowser.platform.windows7?\nbrowser.platform.windows8?\nbrowser.platform.windows8_1?\nbrowser.platform.windows?\nbrowser.platform.windows_mobile?\nbrowser.platform.windows_phone?\nbrowser.platform.windows_rt?\nbrowser.platform.windows_touchscreen_desktop?\nbrowser.platform.windows_vista?\nbrowser.platform.windows_wow64?\nbrowser.platform.windows_x64?\nbrowser.platform.windows_x64_inclusive?\nbrowser.platform.windows_xp?\nbrowser.platform.kai_os?\n```\n\n### Aliases\n\nTo add aliases like `mobile?` and `tablet?` to the base object (e.g\n`browser.mobile?`), require the `browser/aliases` file and extend the\nBrowser::Base object like the following:\n\n```ruby\nrequire \"browser/aliases\"\nBrowser::Base.include(Browser::Aliases)\n\nbrowser = Browser.new(\"Some user agent\")\nbrowser.mobile? #=\u003e false\n```\n\n### What's being detected?\n\n- For a list of platform detections, check\n  [lib/browser/platform.rb](https://github.com/fnando/browser/blob/master/lib/browser/platform.rb)\n- For a list of device detections, check\n  [lib/browser/device.rb](https://github.com/fnando/browser/blob/master/lib/browser/device.rb)\n- For a list of bot detections, check\n  [bots.yml](https://github.com/fnando/browser/blob/master/bots.yml)\n\n### Detecting modern browsers\n\nTo detect whether a browser can be considered as modern or not, create a method\nthat abstracts your versioning constraints. The following example will consider\nany of the following browsers as a modern:\n\n```ruby\n# Expects an Browser instance,\n# like in `Browser.new(user_agent, accept_language: language)`.\ndef modern_browser?(browser)\n  [\n    browser.chrome?(\"\u003e= 65\"),\n    browser.safari?(\"\u003e= 10\"),\n    browser.firefox?(\"\u003e= 52\"),\n    browser.ie?(\"\u003e= 11\") \u0026\u0026 !browser.compatibility_view?,\n    browser.edge?(\"\u003e= 15\"),\n    browser.opera?(\"\u003e= 50\"),\n    browser.facebook?\n      \u0026\u0026 browser.safari_webapp_mode?\n      \u0026\u0026 browser.webkit_full_version.to_i \u003e= 602\n  ].any?\nend\n```\n\n### Rails integration\n\nJust add it to the Gemfile.\n\n```ruby\ngem \"browser\"\n```\n\nThis adds a helper method called `browser`, that inspects your current user\nagent.\n\n```erb\n\u003c% if browser.ie?(6) %\u003e\n  \u003cp class=\"disclaimer\"\u003eYou're running an older IE version. Please update it!\u003c/p\u003e\n\u003c% end %\u003e\n```\n\nIf you want to use Browser on your Rails app but don't want to taint your\ncontroller, use the following line on your Gemfile:\n\n```ruby\ngem \"browser\", require: \"browser/browser\"\n```\n\n### Accept Language\n\nParses the accept-language header from an HTTP request and produces an array of\nlanguage objects sorted by quality.\n\n```ruby\nbrowser = Browser.new(\"Some User Agent\", accept_language: \"en-us\")\n\nbrowser.accept_language.class\n#=\u003e Array\n\nlanguage = browser.accept_language.first\n\nlanguage.code\n#=\u003e \"en\"\n\nlanguage.region\n#=\u003e \"US\"\n\nlanguage.full\n#=\u003e \"en-US\"\n\nlanguage.quality\n#=\u003e 1.0\n\nlanguage.name\n#=\u003e \"English/United States\"\n```\n\nResult is always sorted in quality order from highest to lowest. As per the HTTP\nspec:\n\n- omitting the quality value implies 1.0.\n- quality value equal to zero means that is not accepted by the client.\n\n### Internet Explorer\n\nInternet Explorer has a compatibility view mode that allows newer versions\n(IE8+) to run as an older version. Browser will always return the navigator\nversion, ignoring the compatibility view version, when defined. If you need to\nget the engine's version, you have to use `Browser#msie_version` and\n`Browser#msie_full_version`.\n\nSo, let's say an user activates compatibility view in a IE11 browser. This is\nwhat you'll get:\n\n```ruby\nbrowser.version\n#=\u003e 11\n\nbrowser.full_version\n#=\u003e 11.0\n\nbrowser.msie_version\n#=\u003e 7\n\nbrowser.msie_full_version\n#=\u003e 7.0\n\nbrowser.compatibility_view?\n#=\u003e true\n```\n\nThis behavior changed in `v1.0.0`; previously there wasn't a way of getting the\nreal browser version.\n\n### Safari\n\niOS webviews and web apps aren't detected as Safari anymore, so be aware of that\nif that's your case. You can use a combination of platform and webkit detection\nto do whatever you want.\n\n```ruby\n# iPad's Safari running as web app mode.\nbrowser = Browser.new(\"Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405\")\n\nbrowser.safari?\n#=\u003e false\n\nbrowser.webkit?\n#=\u003e true\n\nbrowser.platform.ios?\n#=\u003e true\n```\n\n### Bots\n\nThe bot detection is quite aggressive. Anything that matches at least one of the\nfollowing requirements will be considered a bot.\n\n- Empty user agent string\n- User agent that matches `/crawl|fetch|search|monitoring|spider|bot/`\n- Any known bot listed under\n  [bots.yml](https://github.com/fnando/browser/blob/master/bots.yml)\n\nTo add custom matchers, you can add a callable object to\n`Browser::Bot.matchers`. The following example matches everything that has a\n`externalhit` substring on it. The bot name will always be `General Bot`.\n\n```ruby\nBrowser::Bot.matchers \u003c\u003c -\u003e(ua, _browser) { ua.match?(/externalhit/i) }\n```\n\nTo clear all matchers, including the ones that are bundled, use\n`Browser::Bot.matchers.clear`. You can re-add built-in matchers by doing the\nfollowing:\n\n```ruby\nBrowser::Bot.matchers += Browser::Bot.default_matchers\n```\n\nTo restore v2's bot detection, remove the following matchers:\n\n```ruby\nBrowser::Bot.matchers.delete(Browser::Bot::KeywordMatcher)\nBrowser::Bot.matchers.delete(Browser::Bot::EmptyUserAgentMatcher)\n```\n\nTo extend the bot list, you can manipulate the methods below:\n\n```ruby\nBrowser::Bot.bots.merge!(new_bots_hash)\nBrowser::Bot.bot_exceptions += new_exceptions\nBrowser::Bot.search_engines.merge!(new_search_engines_hash)\n```\n\n### Middleware\n\nYou can use the `Browser::Middleware` to redirect user agents.\n\n```ruby\nuse Browser::Middleware do\n  redirect_to \"/upgrade\" if browser.ie?\nend\n```\n\nIf you're using Rails, you can use the route helper methods. Just add something\nlike the following to a initializer file (`config/initializers/browser.rb`).\n\n```ruby\nRails.configuration.middleware.use Browser::Middleware do\n  redirect_to upgrade_path if browser.ie?\nend\n```\n\nIf you need access to the `Rack::Request` object (e.g. to exclude a path), you\ncan do so with `request`.\n\n```ruby\nRails.configuration.middleware.use Browser::Middleware do\n  redirect_to upgrade_path if browser.ie? \u0026\u0026 request.env[\"PATH_INFO\"] != \"/exclude_me\"\nend\n```\n\n### Restrictions\n\n- User agent has a size limit of 2048 bytes. This can be customized through\n  `Browser.user_agent_size_limit=(size)`.\n- Accept-Language has a size limit of 2048 bytes. This can be customized through\n  `Browser.accept_language_size_limit=(size)`.\n\nIf size is not respected, then `Browser::Error` is raised.\n\n```ruby\nBrowser.user_agent_size_limit = 4096\nBrowser.accept_language_size_limit = 4096\n```\n\n## Development\n\n### Versioning\n\nThis library follows http://semver.org.\n\n### Writing code\n\nOnce you've made your great commits (include tests, please):\n\n1. [Fork](http://help.github.com/forking/) browser\n2. Create a topic branch - `git checkout -b my_branch`\n3. Push to your branch - `git push origin my_branch`\n4. Create a pull request\n5. That's it!\n\nPlease respect the indentation rules and code style. And use 2 spaces, not tabs.\nAnd don't touch the version thing.\n\n## Configuring environment\n\nTo configure your environment, you must have Ruby and bundler installed. Then\nrun `bundle install` to install all dependencies.\n\nTo run tests, execute `./bin/rake`.\n\n### Adding new features\n\nBefore using your time to code a new feature, open a ticket asking if it makes\nsense and if it's on this project's scope.\n\nDon't forget to add a new entry to `CHANGELOG.md`.\n\n#### Adding a new bot\n\n1. Add the user agent to `test/ua_bots.yml`.\n2. Add the readable name to `bots.yml`. The key must be something that matches\n   the user agent, in lowercased text.\n3. Run tests.\n\nDon't forget to add a new entry to `CHANGELOG.md`.\n\n#### Adding a new search engine\n\n1. Add the user agent to `test/ua_search_engines.yml`.\n2. Add the same user agent to `test/ua_bots.yml`.\n3. Add the readable name to `search_engines.yml`. The key must be something that\n   matches the user agent, in lowercased text.\n4. Run tests.\n\nDon't forget to add a new entry to `CHANGELOG.md`.\n\n#### Wrong browser/platform/device detection\n\nIf you know how to fix it, follow the \"Writing code\" above. Open an issue\notherwise; make sure you fill in the issue template with all the required\ninformation.\n\n## Maintainer\n\n- Nando Vieira - https://nandovieira.com\n\n## Contributors\n\n- https://github.com/fnando/browser/contributors\n\n## License\n\n(The MIT License)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the 'Software'), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","funding_links":["https://github.com/sponsors/fnando","https://paypal.me/nandovieira/🍕"],"categories":["Web Apps, Services \u0026 Interaction","Ruby","Uncategorized","Views and related"],"sub_categories":["User Agent Detection","Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffnando%2Fbrowser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffnando%2Fbrowser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffnando%2Fbrowser/lists"}