Example 1 — Read productSub
Log the current value (same idea as MDN’s example).
console.log("productSub: " + navigator.productSub); How It Works
Sample output shows Chromium/Safari. Firefox typically prints 20100101.

navigator.productSub is a legacy Navigator property. Per MDN it returns either "20030107" or "20100101". Learn the typical values, why sniffing is a bad idea, five examples, and better alternatives.
Read-only property
"20030107" or "20100101"
"20030107"
"20100101"
Widely available
Feature detection
The name productSub looks like a build or product version date. In practice it is a fixed compatibility string that browsers expose as either "20030107" or "20100101".
MDN notes the usual pattern: Apple Safari and Google Chrome return "20030107"; Firefox returns "20100101". Older Internet Explorer returned undefined.
Do not treat productSub as a trustworthy calendar date or as a browser detector. Learn the values for legacy code, then use feature detection in real apps.
It sits next to navigator.product in the same family of old identification labels.
productSub PropertyproductSub is a read-only string on Navigator (or undefined in legacy IE). The date-like shape is historical; modern engines keep a constant token for compatibility.
"20030107" or "20100101" in modern browsers."20030107"."20100101".undefined.General form of the property:
navigator.productSub "20030107" or "20100101".undefined in very old Internet Explorer.console.log(navigator.productSub);
// Chrome / Safari: "20030107"
// Firefox: "20100101"
const known = ["20030107", "20100101"];
const isKnownToken = known.includes(navigator.productSub);
// Prefer feature detection instead of sniffing:
if ("serviceWorker" in navigator) {
// safe to use service workers
} | Goal | Code / note |
|---|---|
| Read the value | navigator.productSub |
| Chrome / Safari (typical) | "20030107" |
| Firefox (typical) | "20100101" |
| IE (legacy) | undefined |
| Type | typeof navigator.productSub // "string" |
| Identify browser? | No — do not sniff with this |
| Better approach | Feature detection on APIs / CSS |
Four facts to remember about navigator.productSub.
2 tokens20030107 / 20100101
stringRead-only
YYYYMMDDNot a real date
avoidUnreliable
product vs productSub vs Feature Detectionproduct | productSub | Feature detection | |
|---|---|---|---|
| Typical value | "Gecko" | "20030107" or "20100101" | N/A |
| Varies by browser? | No (always Gecko) | Historically yes (two tokens) | Checks capability |
| Identifies brand? | No | Unreliable | Checks capability |
| Best for | Legacy trivia | Legacy trivia | Real application logic |
Examples follow MDN navigator.productSub behavior. Prefer Try It Yourself — Chromium/Safari often show 20030107; Firefox shows 20100101.
Read the token and map it to the MDN notes.
productSubLog the current value (same idea as MDN’s example).
console.log("productSub: " + navigator.productSub); Sample output shows Chromium/Safari. Firefox typically prints 20100101.
Label the two MDN values without claiming a brand.
const value = navigator.productSub;
let note = "other / missing";
if (value === "20030107") {
note = "common Chromium / Safari token (MDN)";
} else if (value === "20100101") {
note = "common Firefox token (MDN)";
}
console.log("value: " + value);
console.log("note: " + note);
console.log("Do not use this as a browser detector."); Teaching the MDN mapping is fine; gating features on it is not.
Type checks, related legacy labels, and feature detection.
Confirm the string type and guard for missing values (legacy IE).
const value = navigator.productSub;
const lines = [
"value: " + String(value),
"typeof: " + typeof value,
"isDefined: " + (typeof value !== "undefined")
];
console.log(lines.join("\n")); Modern browsers expose a string. MDN notes IE returned undefined.
Compare productSub with product and other fixed labels.
const lines = [
"product: " + navigator.product,
"productSub: " + navigator.productSub,
"appCodeName: " + navigator.appCodeName,
"appName: " + navigator.appName
];
console.log(lines.join("\n"));
console.log("These are compatibility labels — not brand detectors."); Seeing the family together makes the legacy story clear for beginners.
Keep productSub for learning; use capability checks for features.
const lines = [];
lines.push(
"productSub: " + navigator.productSub + " — ignore for sniffing"
);
lines.push(
"serviceWorker: " +
("serviceWorker" in navigator ? "available" : "missing") +
" — use this for features"
);
console.log(lines.join("\n")); Capability checks stay accurate even when compatibility tokens look like dates.
20030107 / 20100101.productSub.navigator.productSub WorksBrowsers keep a compatibility string that looks like YYYYMMDD.
Your code accesses navigator.productSub.
MDN: 20030107 (Chrome/Safari) or 20100101 (Firefox).
Detect APIs instead of branching on productSub tokens.
"20030107" or "20100101"; IE historically returned undefined.Navigator in modern browsers.navigator.productSub is Baseline Widely available across modern browsers (MDN: since July 2015). Values differ by engine family historically — Chrome/Safari use "20030107", Firefox uses "20100101". IE returned undefined.
A date-like compatibility token. Useful for understanding legacy sniffing — unreliable for identifying browsers in new code.
Bottom line: Read productSub to learn the two common tokens, then ignore it for real feature decisions.
navigator.productSub is a Baseline compatibility string that returns either "20030107" or "20100101". Learn the MDN browser notes for legacy code, then prefer feature detection for real application logic.
Continue with scheduling, product, or the JavaScript hub.
"20030107" or "20100101"undefinedproductSub === "20100101"navigator.productSubproductSubTwo date-like tokens — compatibility labels, not brand detectors.
20030107 / 20100101
Valuecompatibility
Legacydo not use
Avoidread-only
APIfeature detect
ModernThe strings "20030107" and "20100101" look like dates (7 Jan 2003 and 1 Jan 2010), but MDN treats them as fixed compatibility values — not live build timestamps you can trust for version checks.
Experimental API for checking pending input during long tasks.
8 people found this page helpful