Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help needed] Nuxt 3 support #119

Merged
merged 33 commits into from
Nov 12, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4622cb8
Nuxt 3 port
Redemption198 May 19, 2022
37e476c
Update nuxt.config.ts
Redemption198 May 19, 2022
2e32246
Added Nuxt Bridge Compatibility
Redemption198 May 24, 2022
749963f
(chore): update Nuxt to RC4
Redemption198 Jun 27, 2022
3676fe3
(chore): build module (temporarily)
Redemption198 Jun 27, 2022
9c543e2
(feat): add isApple flag
Redemption198 Jul 3, 2022
fab8b95
(fix): typescript types location
Redemption198 Jul 3, 2022
6113034
(fix): typescript $device types
Redemption198 Jul 3, 2022
261aae1
(test) fix typescript support
Redemption198 Jul 3, 2022
1e92fe2
(fix): TypeScript autocomplete
Redemption198 Jul 10, 2022
852dbdd
Remove unused hook
Redemption198 Jul 10, 2022
54cacee
(chore): update Nuxt to RC5
Redemption198 Jul 14, 2022
01d736e
(chore): prepack the module
Redemption198 Jul 15, 2022
6c17aff
(chore): update Nuxt to RC6
Redemption198 Jul 19, 2022
d6d0b92
(chore): update Nuxt to RC8
Redemption198 Aug 13, 2022
fef752e
(chore): update Nuxt to RC9
Redemption198 Sep 6, 2022
0ef0b3c
Update to Nuxt RC10
Redemption198 Sep 14, 2022
fe7ebba
Update to Nuxt RC11
Redemption198 Sep 22, 2022
f9d0477
Use slice instead of substr (deprecated)
Redemption198 Sep 22, 2022
7e78f87
Add useDevice() composable
Redemption198 Oct 6, 2022
4a57c2d
Update README.md
Redemption198 Oct 6, 2022
850f283
Update @nuxt/kit to RC11
Redemption198 Oct 11, 2022
3108fe4
Restore bot-regex script
Redemption198 Oct 17, 2022
84b575e
Remove unnecessary options merge and lowered minimum Nuxt version to RC5
Redemption198 Oct 17, 2022
bdf92a8
Revert "Remove unnecessary options merge and lowered minimum Nuxt ver…
Redemption198 Oct 17, 2022
78bf0cf
Added Tests
Redemption198 Oct 17, 2022
2136ea0
Bump deps
Redemption198 Oct 18, 2022
e81cb35
Restore test workflow and publish scripts, remove dist
Redemption198 Nov 4, 2022
3f6767b
Update package.json
Redemption198 Nov 4, 2022
772c5f7
Update test.yaml
Redemption198 Nov 4, 2022
bbc5599
Update package.json
Redemption198 Nov 4, 2022
350f6bc
Update package.json
Redemption198 Nov 4, 2022
1d79565
Update package.json
Redemption198 Nov 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@
node_modules
dist
.nuxt
coverage

# Plugin
lib/plugin.js
coverage
10 changes: 10 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": [
"@nuxtjs/eslint-config-typescript"
],
"rules": {
"@typescript-eslint/no-unused-vars": [
"off"
]
}
}
6 changes: 0 additions & 6 deletions .eslintrc.js

This file was deleted.

18 changes: 0 additions & 18 deletions .github/workflows/test.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ node_modules
.vscode
.DS_STORE
coverage
dist
.output
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,18 @@ yarn add --dev @nuxtjs/device
npm install -D @nuxtjs/device
```

Add it to the `buildModules` section of your `nuxt.config`:
Add it to the `modules` section of your `nuxt.config`:

```js
{
buildModules: [
modules: [
'@nuxtjs/device',
]
}
```

That's it, you can now use `$device` in your [Nuxt](https://nuxtjs.org) app ✨

## TypeScript support

Add the types to your `"types"` array in `tsconfig.json` after the `@nuxt/types` entry.

:warning: Use `@nuxt/vue-app` instead of `@nuxt/types` for nuxt < 2.9.

```json
{
"compilerOptions": {
"types": ["@nuxt/types", "@nuxtjs/device"]
}
}
```

## Flags

You can use these flags to detect the device type.
Expand All @@ -59,6 +45,7 @@ $device.isDesktopOrTablet
$device.isIos
$device.isWindows
$device.isMacOS
$device.isApple
$device.isAndroid
$device.isFirefox
$device.isEdge
Expand All @@ -72,6 +59,17 @@ The user agent is also injected an accessible with `$device.userAgent`.

## Usage

### Composable

You can use the `useDevice()` composable inside a `script setup` to access the flags.

```js
<script setup>
const { isMobile } = useDevice();
</script>
```


### Switch a view

```html
Expand Down Expand Up @@ -117,7 +115,7 @@ export default function ({ $device }) {

```js
{
buildModules: ['@nuxtjs/device'],
modules: ['@nuxtjs/device'],
device: {
defaultUserAgent: 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Mobile Safari/537.36'
}
Expand All @@ -128,7 +126,7 @@ export default function ({ $device }) {

```js
{
buildModules: ['@nuxtjs/device'],
modules: ['@nuxtjs/device'],
device: {
refreshOnResize: true
}
Expand Down
5 changes: 5 additions & 0 deletions dist/module.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(...args) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why you push the dist folder Ideally this will be auto-generated and only available on NPM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct, that was intentional because as requested here, people were trying to install it from GitHub. It wasn't included when I opened this PR, but 5 months passed and no one from this repository showed up so I temporarily included it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, got it 👍🏻
Yes, that makes sense - alternatively feel free to publish a temp package so people can use that while the PR is pending 😋

return import('./module.mjs').then(m => m.default.call(this, ...args))
}
const _meta = module.exports.meta = require('./module.json')
module.exports.getMeta = () => Promise.resolve(_meta)
25 changes: 25 additions & 0 deletions dist/module.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as _nuxt_schema from '@nuxt/schema';

interface ModuleOptions {
/**
* Enable Device Module
* @default true
* @type boolean
*/
enabled: boolean;
/**
* Device Module Default User Agent
* @default 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36'
* @type string
*/
defaultUserAgent: string;
/**
* Refresh Device Module Values On Window Resize
* @default false
* @type boolean
*/
refreshOnResize: boolean;
}
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;

export { ModuleOptions, _default as default };
9 changes: 9 additions & 0 deletions dist/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "device-module",
"configKey": "device",
"compatibility": {
"nuxt": "^3.0.0-rc.11 || ^2.16.0",
"bridge": true
},
"version": "3.0.0"
}
37 changes: 37 additions & 0 deletions dist/module.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { resolve } from 'path';
import { fileURLToPath } from 'url';
import { defu } from 'defu';
import { defineNuxtModule, addPlugin } from '@nuxt/kit';

const module = defineNuxtModule({
meta: {
name: "device-module",
configKey: "device",
compatibility: {
nuxt: "^3.0.0-rc.11 || ^2.16.0",
bridge: true
}
},
defaults: {
enabled: true,
defaultUserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36",
refreshOnResize: false
},
setup(options, nuxt) {
if (options.enabled) {
nuxt.options.runtimeConfig.public.device = defu(nuxt.options.runtimeConfig.public.device, {
enabled: options.enabled,
defaultUserAgent: options.defaultUserAgent,
refreshOnResize: options.refreshOnResize
});
const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url));
nuxt.options.build.transpile.push(runtimeDir);
addPlugin(resolve(runtimeDir, "plugin"));
nuxt.hook("imports:dirs", (dirs) => {
dirs.push(resolve(runtimeDir, "composables"));
});
}
}
});

export { module as default };
2 changes: 2 additions & 0 deletions dist/runtime/composables/useDevice.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import type { Device } from '../types';
export default function (): Device;
4 changes: 4 additions & 0 deletions dist/runtime/composables/useDevice.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { useNuxtApp } from "#app";
export default function() {
return useNuxtApp().$device;
}
2 changes: 2 additions & 0 deletions dist/runtime/generateFlags.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import type { Device } from './types';
export default function generateFlags(headers: any, userAgent: string): Device;
102 changes: 102 additions & 0 deletions dist/runtime/generateFlags.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const REGEX_MOBILE1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|FBAN|FBAV|fennec|hiptop|iemobile|ip(hone|od)|Instagram|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|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|xda|xiino/i;
const REGEX_MOBILE2 = /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\-/i;
function isMobile(a) {
return REGEX_MOBILE1.test(a) || REGEX_MOBILE2.test(a.slice(0, 4));
}
const REGEX_MOBILE_OR_TABLET1 = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|FBAN|FBAV|fennec|hiptop|iemobile|ip(hone|od)|Instagram|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|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|xda|xiino|android|ipad|playbook|silk/i;
const REGEX_MOBILE_OR_TABLET2 = /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\-/i;
const REGEX_CRAWLER = /Googlebot\/|Googlebot-Mobile|Googlebot-Image|Googlebot-News|Googlebot-Video|AdsBot-Google([^-]|$)|AdsBot-Google-Mobile|Feedfetcher-Google|Mediapartners-Google|Mediapartners \(Googlebot\)|APIs-Google|bingbot|Slurp|[wW]get|LinkedInBot|Python-urllib|python-requests|aiohttp|httpx|libwww-perl|httpunit|nutch|Go-http-client|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|BIGLOTRON|Teoma|convera|seekbot|Gigabot|Gigablast|exabot|ia_archiver|GingerCrawler|webmon |HTTrack|grub.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|findlink|msrbot|panscient|yacybot|AISearchBot|ips-agent|tagoobot|MJ12bot|woriobot|yanga|buzzbot|mlbot|YandexBot|YandexImages|YandexAccessibilityBot|YandexMobileBot|YandexMetrika|YandexTurbo|YandexImageResizer|YandexVideo|YandexAdNet|YandexBlogs|YandexCalendar|YandexDirect|YandexFavicons|YaDirectFetcher|YandexForDomain|YandexMarket|YandexMedia|YandexMobileScreenShotBot|YandexNews|YandexOntoDB|YandexPagechecker|YandexPartner|YandexRCA|YandexSearchShop|YandexSitelinks|YandexSpravBot|YandexTracker|YandexVertis|YandexVerticals|YandexWebmaster|YandexScreenshotBot|purebot|Linguee Bot|CyberPatrol|voilabot|Baiduspider|citeseerxbot|spbot|twengabot|postrank|TurnitinBot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|ezooms|dotbot|Mail.RU_Bot|discobot|heritrix|findthatfile|europarchive.org|NerdByNature.Bot|sistrix crawler|Ahrefs(Bot|SiteAudit)|fuelbot|CrunchBot|IndeedBot|mappydata|woobot|ZoominfoBot|PrivacyAwareBot|Multiviewbot|SWIMGBot|Grobbot|eright|Apercite|semanticbot|Aboundex|domaincrawler|wbsearchbot|summify|CCBot|edisterbot|seznambot|ec2linkfinder|gslfbot|aiHitBot|intelium_bot|facebookexternalhit|Yeti|RetrevoPageAnalyzer|lb-spider|Sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net.com.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|it2media-domain-crawler|ip-web-crawler.com|siteexplorer.info|elisabot|proximic|changedetection|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|CC Metadata Scaper|g00g1e.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Twitterbot|cXensebot|smtbot|bnf.fr_bot|A6-Indexer|ADmantX|Facebot|OrangeBot\/|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|S[eE][mM]rushBot|yoozBot|lipperhey|Y!J|Domain Re-Animator Bot|AddThis|Screaming Frog SEO Spider|MetaURI|Scrapy|Livelap[bB]ot|OpenHoseBot|CapsuleChecker|[email protected]|IstellaBot|DeuSu\/|betaBot|Cliqzbot\/|MojeekBot\/|netEstate NE Crawler|SafeSearch microdata crawler|Gluten Free Crawler\/|Sonic|Sysomos|Trove|deadlinkchecker|Slack-ImgProxy|Embedly|RankActiveLinkBot|iskanie|SafeDNSBot|SkypeUriPreview|Veoozbot|Slackbot|redditbot|datagnionbot|Google-Adwords-Instant|adbeat_bot|WhatsApp|contxbot|pinterest.com.bot|electricmonk|GarlikCrawler|BingPreview\/|vebidoobot|FemtosearchBot|Yahoo Link Preview|MetaJobBot|DomainStatsBot|mindUpBot|Daum\/|Jugendschutzprogramm-Crawler|Xenu Link Sleuth|Pcore-HTTP|moatbot|KosmioBot|pingdom|AppInsights|PhantomJS|Gowikibot|PiplBot|Discordbot|TelegramBot|Jetslide|newsharecounts|James BOT|Bark[rR]owler|TinEye|SocialRankIOBot|trendictionbot|Ocarinabot|epicbot|Primalbot|DuckDuckGo-Favicons-Bot|GnowitNewsbot|Leikibot|LinkArchiver|YaK\/|PaperLiBot|Digg Deeper|dcrawl|Snacktory|AndersPinkBot|Fyrebot|EveryoneSocialBot|Mediatoolkitbot|Luminator-robots|ExtLinksBot|SurveyBot|NING\/|okhttp|Nuzzel|omgili|PocketParser|YisouSpider|um-LN|ToutiaoSpider|MuckRack|Jamie's Spider|AHC\/|NetcraftSurveyAgent|Laserlikebot|^Apache-HttpClient|AppEngine-Google|Jetty|Upflow|Thinklab|Traackr.com|Twurly|Mastodon|http_get|DnyzBot|botify|007ac9 Crawler|BehloolBot|BrandVerity|check_http|BDCbot|ZumBot|EZID|ICC-Crawler|ArchiveBot|^LCC |filterdb.iss.net\/crawler|BLP_bbot|BomboraBot|Buck\/|Companybook-Crawler|Genieo|magpie-crawler|MeltwaterNews|Moreover|newspaper\/|ScoutJet|(^| )sentry\/|StorygizeBot|UptimeRobot|OutclicksBot|seoscanners|Hatena|Google Web Preview|MauiBot|AlphaBot|SBL-BOT|IAS crawler|adscanner|Netvibes|acapbot|Baidu-YunGuanCe|bitlybot|blogmuraBot|Bot.AraTurka.com|bot-pge.chlooe.com|BoxcarBot|BTWebClient|ContextAd Bot|Digincore bot|Disqus|Feedly|Fetch\/|Fever|Flamingo_SearchEngine|FlipboardProxy|g2reader-bot|G2 Web Services|imrbot|K7MLWCBot|Kemvibot|Landau-Media-Spider|linkapediabot|vkShare|Siteimprove.com|BLEXBot\/|DareBoost|ZuperlistBot\/|Miniflux\/|Feedspot|Diffbot\/|SEOkicks|tracemyfile|Nimbostratus-Bot|zgrab|PR-CY.RU|AdsTxtCrawler|Datafeedwatch|Zabbix|TangibleeBot|google-xrawler|axios|Amazon CloudFront|Pulsepoint|CloudFlare-AlwaysOnline|Google-Structured-Data-Testing-Tool|WordupInfoSearch|WebDataStats|HttpUrlConnection|Seekport Crawler|ZoomBot|VelenPublicWebCrawler|MoodleBot|jpg-newsbot|outbrain|W3C_Validator|Validator\.nu|W3C-checklink|W3C-mobileOK|W3C_I18n-Checker|FeedValidator|W3C_CSS_Validator|W3C_Unicorn|Google-PhysicalWeb|Blackboard|ICBot\/|BazQux|Twingly|Rivva|Experibot|awesomecrawler|Dataprovider.com|GroupHigh\/|theoldreader.com|AnyEvent|Uptimebot\.org|Nmap Scripting Engine|2ip.ru|Clickagy|Caliperbot|MBCrawler|online-webceo-bot|B2B Bot|AddSearchBot|Google Favicon|HubSpot|Chrome-Lighthouse|HeadlessChrome|CheckMarkNetwork\/|www\.uptime\.com|Streamline3Bot\/|serpstatbot\/|MixnodeCache\/|^curl|SimpleScraper|RSSingBot|Jooblebot|fedoraplanet|Friendica|NextCloud|Tiny Tiny RSS|RegionStuttgartBot|Bytespider|Datanyze|Google-Site-Verification|TrendsmapResolver|tweetedtimes|NTENTbot|Gwene|SimplePie|SearchAtlas|Superfeedr|feedbot|UT-Dorkbot|Amazonbot|SerendeputyBot|Eyeotabot|officestorebot|Neticle Crawler|SurdotlyBot|LinkisBot|AwarioSmartBot|AwarioRssBot|RyteBot|FreeWebMonitoring SiteChecker|AspiegelBot|NAVER Blog Rssbot|zenback bot|SentiBot|Domains Project\/|Pandalytics|VKRobot|bidswitchbot|tigerbot|NIXStatsbot|Atom Feed Robot|Curebot|PagePeeker\/|Vigil\/|rssbot\/|startmebot\/|JobboerseBot|seewithkids|NINJA bot|Cutbot|BublupBot|BrandONbot|RidderBot|Taboolabot|Dubbotbot|FindITAnswersbot|infoobot|Refindbot|BlogTraffic\/\d\.\d+ Feed-Fetcher|SeobilityBot|Cincraw|Dragonbot|VoluumDSP-content-bot|FreshRSS|BitBot|^PHP-Curl-Class|Google-Certificates-Bridge/;
function isMobileOrTablet(a) {
return REGEX_MOBILE_OR_TABLET1.test(a) || REGEX_MOBILE_OR_TABLET2.test(a.slice(0, 4));
}
function isIos(a) {
return /iPad|iPhone|iPod/.test(a);
}
function isAndroid(a) {
return /android/i.test(a);
}
function isWindows(a) {
return /Windows/.test(a);
}
function isMacOS(a) {
return /Mac OS X/.test(a);
}
const browsers = [
{ name: "Samsung", test: /SamsungBrowser/i },
{ name: "Edge", test: /edg([ea]|ios|)\//i },
{ name: "Firefox", test: /firefox|iceweasel|fxios/i },
{ name: "Chrome", test: /chrome|crios|crmo/i },
{ name: "Safari", test: /safari|applewebkit/i }
];
function getBrowserName(a) {
for (const b of browsers) {
if (b.test.test(a)) {
return b.name;
}
}
return "";
}
export default function generateFlags(headers, userAgent) {
let mobile = false;
let mobileOrTablet = false;
let ios = false;
let android = false;
if (userAgent === "Amazon CloudFront") {
if (headers["cloudfront-is-mobile-viewer"] === "true") {
mobile = true;
mobileOrTablet = true;
}
if (headers["cloudfront-is-tablet-viewer"] === "true") {
mobile = false;
mobileOrTablet = true;
}
} else if (headers && headers["cf-device-type"]) {
switch (headers["cf-device-type"]) {
case "mobile":
mobile = true;
mobileOrTablet = true;
break;
case "tablet":
mobile = false;
mobileOrTablet = true;
break;
case "desktop":
mobile = false;
mobileOrTablet = false;
break;
}
} else {
mobile = isMobile(userAgent);
mobileOrTablet = isMobileOrTablet(userAgent);
ios = isIos(userAgent);
android = isAndroid(userAgent);
}
const windows = isWindows(userAgent);
const macOS = isMacOS(userAgent);
const browserName = getBrowserName(userAgent);
const isSafari = browserName === "Safari";
const isFirefox = browserName === "Firefox";
const isEdge = browserName === "Edge";
const isChrome = browserName === "Chrome";
const isSamsung = browserName === "Samsung";
const isCrawler = REGEX_CRAWLER.test(userAgent);
return {
userAgent,
isMobile: mobile,
isMobileOrTablet: mobileOrTablet,
isTablet: !mobile && mobileOrTablet,
isDesktop: !mobileOrTablet,
isIos: ios,
isAndroid: android,
isWindows: windows,
isMacOS: macOS,
isApple: macOS || ios,
isDesktopOrTablet: !mobile,
isSafari,
isFirefox,
isEdge,
isChrome,
isSamsung,
isCrawler
};
}
2 changes: 2 additions & 0 deletions dist/runtime/plugin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare const _default: any;
export default _default;
36 changes: 36 additions & 0 deletions dist/runtime/plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { defineNuxtPlugin, useRuntimeConfig, useRequestHeaders } from "#app";
import { reactive } from "vue";
import generateFlags from "./generateFlags.mjs";
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const DEFAULT_USER_AGENT = config.public.device.defaultUserAgent;
const REFRESH_ON_RESIZE = config.public.device.refreshOnResize;
if (nuxtApp.ssrContext) {
const headers = useRequestHeaders();
const userAgent2 = headers["user-agent"] || DEFAULT_USER_AGENT;
const flags2 = reactive(generateFlags(headers, userAgent2));
return {
Redemption198 marked this conversation as resolved.
Show resolved Hide resolved
provide: {
device: flags2
}
};
}
const userAgent = navigator.userAgent || DEFAULT_USER_AGENT;
const flags = reactive(generateFlags({}, userAgent));
if (REFRESH_ON_RESIZE) {
window.addEventListener("resize", () => {
setTimeout(() => {
const newFlags = generateFlags({}, navigator.userAgent || DEFAULT_USER_AGENT);
Object.entries(newFlags).forEach((entry) => {
const [key, value] = entry;
flags[key] = value;
});
}, 50);
});
}
return {
provide: {
device: flags
}
};
});
19 changes: 19 additions & 0 deletions dist/runtime/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export type Device = {
userAgent: string
isDesktop: boolean
isIos: boolean
isAndroid: boolean
isMobile: boolean
isMobileOrTablet: boolean
isDesktopOrTablet: boolean
isTablet: boolean
isWindows: boolean
isMacOS: boolean
isApple: boolean
isSafari: boolean
isFirefox: boolean
isEdge: boolean
isChrome: boolean
isSamsung: boolean
isCrawler: boolean
}
10 changes: 10 additions & 0 deletions dist/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import { ModuleOptions } from './module'

declare module '@nuxt/schema' {
interface NuxtConfig { ['device']?: Partial<ModuleOptions> }
interface NuxtOptions { ['device']?: ModuleOptions }
}


export { default } from './module'
Loading