Example 1 — Read vendorSub
Log the current value (shown with JSON.stringify so empty is visible).
console.log(JSON.stringify(navigator.vendorSub)); How It Works
MDN: the value is always the empty string in any browser.

navigator.vendorSub is a Baseline Navigator property. Per MDN, its value is always the empty string in any browser. Learn what that means, how it differs from vendor, five examples, and why sniffing with it is useless.
Read-only property
"" always
Widely available
Compatibility
Useless
Feature detection
Next to navigator.vendor sits navigator.vendorSub — a companion “sub” field that sounds like it should hold a vendor version or subtitle.
In reality, MDN is crystal clear: the value is always the empty string, in any browser.
vendorSub is not undefined or null. It is the empty string "", so typeof navigator.vendorSub === "string" and length is 0.
Learn it so legacy Navigator tables make sense — then ignore it for real app logic.
vendorSub PropertyThink of vendorSub as a reserved legacy slot that modern browsers keep empty for compatibility — similar in spirit to other fixed Navigator labels.
"" in conforming / mainstream browsers (MDN).vendor only for learning: vendor may vary; vendorSub does not.productSub (not empty — returns fixed tokens).General form of the property:
navigator.vendorSub "").console.log(navigator.vendorSub); // ""
// Always true in modern browsers:
const isEmpty = navigator.vendorSub === "";
console.log(typeof navigator.vendorSub); // "string"
console.log(navigator.vendorSub.length); // 0
// Prefer feature detection for real features:
if ("serviceWorker" in navigator) {
// safe to use service workers
} | Goal | Code |
|---|---|
| Read vendorSub | navigator.vendorSub |
| Expected value | "" |
| Empty check | navigator.vendorSub === "" |
| Type | typeof navigator.vendorSub // "string" |
| Length | navigator.vendorSub.length // 0 |
| Identify browser? | No — always empty |
| Better approach | Feature detection on APIs |
Four facts to remember about navigator.vendorSub.
""Every browser
stringRead-only
BaselineSince Jul 2015
uselessAlways empty
vendor vs vendorSub vs productSubvendor | vendorSub | productSub | |
|---|---|---|---|
| Typical value | "Google Inc." / Apple / "" | "" always | "20030107" / "20100101" |
| Varies by browser? | Yes (few cases) | No | Yes (two tokens) |
| Useful for sniffing? | Weak | No | No |
| Best for | Learning / coarse logs | Understanding legacy API | Legacy trivia |
Examples follow MDN navigator.vendorSub behavior. Prefer Try It Yourself — you should see an empty string in any modern browser.
Read the empty string and confirm it is always empty.
vendorSubLog the current value (shown with JSON.stringify so empty is visible).
console.log(JSON.stringify(navigator.vendorSub)); MDN: the value is always the empty string in any browser.
""Show the equality check beginners might try for sniffing (and why it fails).
const isEmpty = navigator.vendorSub === "";
console.log("vendorSub === \"\": " + isEmpty);
console.log("This does NOT identify a browser brand."); The check is true everywhere — so it cannot tell browsers apart.
Type checks, compare with vendor, and prefer feature detection.
Confirm empty is still a string with length 0.
const v = navigator.vendorSub;
const lines = [
"value: " + JSON.stringify(v),
"typeof: " + typeof v,
"length: " + v.length,
"is undefined?: " + (v === undefined),
"is null?: " + (v === null)
];
console.log(lines.join("\n")); Beginners often confuse empty string with missing. Here the property exists and is intentionally blank.
vendorShow that vendor can vary while vendorSub stays empty.
const lines = [
"vendor: " + JSON.stringify(navigator.vendor),
"vendorSub: " + JSON.stringify(navigator.vendorSub),
"productSub: " + JSON.stringify(navigator.productSub)
];
console.log(lines.join("\n"));
console.log("vendorSub stays empty even when vendor is not."); Side-by-side logging makes the “always empty” rule obvious for beginners.
Keep vendorSub for trivia; use capability checks for features.
const lines = [];
lines.push(
"vendorSub: " + JSON.stringify(navigator.vendorSub) + " — always empty"
);
lines.push(
"serviceWorker: " +
("serviceWorker" in navigator ? "available" : "missing") +
" — use this for features"
);
console.log(lines.join("\n")); An empty compatibility field cannot drive feature decisions — APIs can.
vendorSub."".navigator.vendorSub WorksMDN: always the empty string in any browser.
navigator.vendorSub returns "".
Chrome, Firefox, Safari, Edge — still empty.
Detect APIs instead of reading vendorSub.
"" in any browser (MDN).Navigator.navigator.vendorSub is Baseline Widely available across modern browsers (MDN: since July 2015). Every browser returns the empty string "" — useful for learning, useless for brand detection.
Always "". A legacy companion to vendor that never carries a subtitle in modern browsers.
Bottom line: Read navigator.vendorSub once to confirm it is empty, then ignore it for real feature decisions.
navigator.vendorSub is a Baseline compatibility string that is always empty. Learn it so Navigator docs make sense, remember it cannot identify browsers, and prefer feature detection for real application logic.
Continue with virtualKeyboard, vendor, or the JavaScript hub.
"" everywhereJSON.stringify when logging so empty is visiblevendor only for learningvendorSubundefinednavigator.vendorSubvendorSubAlways empty — Baseline compatibility string, not a brand detector.
""
Valuesame empty
MDNread-only
APIuseless
Avoidfeature detect
BestFirefox’s navigator.vendor is also empty, but that is a Firefox-specific vendor quirk. vendorSub is empty in every browser — including Chrome and Safari, where vendor is not empty.
Experimental API for on-screen keyboard geometry and overlays.
8 people found this page helpful