nw.js icon indicating copy to clipboard operation
nw.js copied to clipboard

Overriding user agent string clears navigator.userAgentData

Open AshleyScirra opened this issue 2 years ago • 3 comments

NWJS Version : 0.63 Operating System : Windows 11

Expected behavior

The navigator.userAgentData API is a modern replacement for the user agent string, supported since Chromium 90.

In NW.js this should return platform details such as the OS, and a list of brands. For example Google Chrome returns the following brands:

  • { brand: " Not A;Brand", version: "100" }
  • { brand: "Chromium", version: "100" }
  • { brand: "Google Chrome", version: "100" }

NW.js probably ought to list something like:

  • { brand: "Chromium", version: "100" }
  • { brand: "NW.js", version: "0.63" }

Actual behavior

In NW.js navigator.userAgentData appears to be completely empty. It does not even list the platform as "Windows", it's just an empty string. And the "brands" array is empty. There is no useful information to be found at all.

How to reproduce

Just open a console and type navigator.userAgentData and inspect the provided data.

Note also the getHighEntropyValues API can return more detailed information, e.g.:

await navigator.userAgentData.getHighEntropyValues([
	"platformVersion", "fullVersionList"
]);

This can be used to detect the OS like Windows 11 (not currently possible via the UA string), as well as the detailed browser version such as 99.0.4844.84.

AshleyScirra avatar Apr 07 '22 09:04 AshleyScirra

I am not able to reproduce this. I ran the code you listed and got the following.

NW.js brands[0].brand brands[0].version brands[1].brand brands[1].version fullVersionList[0].brand fullVersionList[0].version fullVersionList[1].brand fullVersionList[1].version mobile platform platformVersion
0.62.2-x64-sdk "(Not(A:Brand" "8" "Chromium" "99" "(Not(A:Brand" "8.0.0.0" "Chromium" "99.0.4844.84" false "Windows" "10.0.0"
0.63.0-x64-sdk "(Not(A:Brand" "8" "Chromium" "100" "(Not(A:Brand" "8.0.0.0" "Chromium" "100.0.4896.60" false "Windows" "10.0.0"
0.63.1-x64-sdk "(Not(A:Brand" "8" "Chromium" "100" "(Not(A:Brand" "8.0.0.0" "Chromium" "100.0.4896.127" false "Windows" "10.0.0"

If you are looking for a way to detect if your code is running in NW.js or a regular browser I would use const isDesktop = !!window.nw;. If you are looking for the NW.js version number then all details are available in process.versions.

TheJaredWilcurt avatar Apr 27 '22 17:04 TheJaredWilcurt

work also on my side ! image

jonlepage avatar Apr 27 '22 22:04 jonlepage

Ah, you're right, it turns out it does work out of the box... the problem is actually that if you specify "user-agent" in package.json, it also clears navigator.userAgentData, which is what I had been doing in my test. Minimal repro: package.zip

I don't think that should happen - I'd expect the "user-agent" field to only replace the user agent string. Clearing the user agent data makes it useless, so if that is supposed to happen for some reason, then there should be some other way of specifying what the user agent data ought to be instead. I think the best solution is to make the user agent string override not affect userAgentData at all.

I would also say NW.js deserves its own entry in brands - sure, you can find it other ways, but it's nice to write web-compatible code that works in browsers too.

AshleyScirra avatar Apr 28 '22 10:04 AshleyScirra