JavaScript Document hasPrivateToken() Method

Intermediate
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Experimental
Instance method

What You’ll Learn

document.hasPrivateToken() is an instance method that asks whether the browser already stores a private state token from a given issuer (see MDN Document: hasPrivateToken()). Learn the Promise boolean result, issuer URLs, secure-context rules, exceptions, and safe feature detection.

01

Kind

Instance method

02

Arg

issuer URL

03

Returns

Promise<boolean>

04

Context

Secure (HTTPS)

05

API

Private State Token

06

Status

Experimental

Introduction

Private State Tokens help sites prove “this browser already completed a trust check with issuer X” without exposing a classic third-party cookie. Before requesting a new token, you can ask: do we already have one?

MDN: hasPrivateToken() returns a promise that fulfills with a boolean indicating whether the browser has a private state token stored from a particular issuer server.

💡
Think: “token already on file for this issuer?”

1) Feature-detect document.hasPrivateToken
2) Pass a valid issuer URL string
3) await the Promise → true / false
4) Only then decide whether to request a new token

🔒
Secure context required

MDN: NotAllowedError is thrown if the document is not loaded in a secure context. Use HTTPS (or localhost) when experimenting.

Related tutorials: hasFocus(), getSelection(), hasRedemptionRecord().

Understanding document.hasPrivateToken()

An instance method on the Document interface from the Private State Token API (MDN). Call it on document, not as a free-floating global.

  • issuer — string URL of an issuer server (MDN).
  • Return value — a Promise that resolves to a boolean (MDN).
  • true — a private state token from that issuer is stored.
  • false — no stored token for that issuer (you may request one).
  • Experimental — limited browser support; feature-detect first (MDN).
  • Issuer limit — MDN: max two issuers per top-level origin; exceeding throws NotAllowedError.

📝 Syntax

General form of Document.hasPrivateToken (MDN):

JavaScript
hasPrivateToken(issuer)

Parameters

  • issuer — a string representing the URL of an issuer server (MDN). Prefer a full absolute URL such as "https://issuer.example".

Return value

A Promise that resolves with a boolean value indicating whether the browser has a private state token stored from the specified issuer server (MDN).

Exceptions (MDN)

  • InvalidStateError — the current Document is not yet active.
  • NotAllowedError — not a secure context, or the maximum number of issuers per top-level origin (two) has been exceeded.
  • TypeErrorissuer is not a valid URL.

MDN-inspired sample (instance call)

JavaScript
const hasToken = await document.hasPrivateToken("https://issuer.example");
if (!hasToken) {
  await fetch(
    "https://issuer.example/.well-known/private-state-token/issuance",
    {
      method: "POST",
      privateToken: {
        version: 1,
        operation: "token-request",
      },
    },
  );
}

Tip: MDN’s snippet shows the same flow. This tutorial calls document.hasPrivateToken(...) because the method is an instance method on Document.

⚡ Quick Reference

GoalCode
Feature-detecttypeof document.hasPrivateToken === "function"
Check issuerawait document.hasPrivateToken("https://issuer.example")
Request if missingMDN: fetch(..., { privateToken: { version: 1, operation: "token-request" } })
Secure context?window.isSecureContext
Invalid URLThrows TypeError (MDN)
MDN statusExperimental — limited availability

🔍 At a Glance

Four facts about document.hasPrivateToken().

Returns
Promise

boolean

Arg
issuer

URL string

Context
secure

HTTPS

Status
Experimental

MDN

📋 Success path vs common failures

SituationLikely resultWhat to do
Supported browser + HTTPS + valid issuerPromise → true/falseBranch on the boolean (MDN)
Method missingundefined functionFeature-detect; skip or polyfill strategy
HTTP pageNotAllowedError (MDN)Use a secure context
Bad issuer stringTypeError (MDN)Pass a valid absolute URL
Too many issuersNotAllowedError (max two) (MDN)Reduce issuer usage per origin

Examples Gallery

Examples follow MDN Document: hasPrivateToken() with beginner-safe feature detection. Many demos will report “not supported” outside Chromium.

📚 Getting Started

Detect support before calling the experimental method.

Example 1 — Feature-detect safely

Always check that the function exists before awaiting it.

JavaScript
if (typeof document.hasPrivateToken === "function") {
  console.log("hasPrivateToken is available");
} else {
  console.log("hasPrivateToken is not supported in this browser");
}
Try It Yourself

How It Works

Experimental APIs come and go. Detection keeps demos and production code from throwing TypeError: ... is not a function.

Example 2 — Await the issuer boolean

MDN: resolve to whether a token from that issuer is stored.

JavaScript
async function checkIssuer(issuer) {
  if (typeof document.hasPrivateToken !== "function") {
    return "unsupported";
  }
  const hasToken = await document.hasPrivateToken(issuer);
  return hasToken ? "token present" : "no token yet";
}

checkIssuer("https://issuer.example").then(console.log);
Try It Yourself

How It Works

Use a real absolute issuer URL. An invalid string can reject with TypeError (MDN).

📈 Practical Patterns

Request tokens, catch exceptions, and verify HTTPS.

Example 3 — Request a token only if missing

MDN flow: check first, then POST to the issuance well-known URL.

JavaScript
async function ensureToken(issuer) {
  if (typeof document.hasPrivateToken !== "function") {
    throw new Error("Private State Tokens not supported");
  }

  const hasToken = await document.hasPrivateToken(issuer);
  if (!hasToken) {
    await fetch(`${issuer}/.well-known/private-state-token/issuance`, {
      method: "POST",
      privateToken: {
        version: 1,
        operation: "token-request",
      },
    });
  }
  return hasToken;
}
Try It Yourself

How It Works

Checking first avoids unnecessary issuance traffic. The privateToken fetch option is part of the same experimental API family.

Example 4 — Catch MDN exceptions

Wrap calls so invalid URLs or policy limits fail gracefully.

JavaScript
async function safeHasToken(issuer) {
  if (typeof document.hasPrivateToken !== "function") {
    return { ok: false, reason: "unsupported" };
  }
  try {
    const hasToken = await document.hasPrivateToken(issuer);
    return { ok: true, hasToken };
  } catch (err) {
    // TypeError | NotAllowedError | InvalidStateError (MDN)
    return { ok: false, reason: err.name, message: err.message };
  }
}

safeHasToken("not-a-url").then(console.log);
Try It Yourself

How It Works

MDN documents three failure modes. Catching by err.name keeps UI messages clear for beginners and operators.

Example 5 — Guard with isSecureContext

MDN: insecure contexts reject with NotAllowedError.

JavaScript
async function checkWhenSecure(issuer) {
  if (!window.isSecureContext) {
    return "Need HTTPS (or localhost) first";
  }
  if (typeof document.hasPrivateToken !== "function") {
    return "API missing";
  }
  return (await document.hasPrivateToken(issuer)) ? "yes" : "no";
}

checkWhenSecure("https://issuer.example").then(console.log);
Try It Yourself

How It Works

Checking isSecureContext early gives a clearer message than waiting for NotAllowedError.

🚀 Common Use Cases

  • Skip redundant issuance — only request a token when MDN’s boolean is false.
  • Privacy-preserving trust — Private State Tokens as a cookie alternative family (MDN API).
  • Feature-gated UX — hide token flows when the method is unsupported.
  • Secure-only demos — enforce HTTPS before calling the API.
  • Issuer budgeting — stay within the two-issuer-per-origin limit (MDN).
  • Learning / migration — understand experimental privacy APIs without relying on them yet in production.

🧠 How hasPrivateToken() Works

1

Pass an issuer URL

Must be a valid URL string identifying the issuer server (MDN).

Input
2

Browser checks stored tokens

Looks for a private state token from that issuer (MDN).

Lookup
3

Promise resolves to a boolean

true if present, false if not (MDN).

Result
4

Decide next step

Skip work, or request issuance with fetch + privateToken.

📝 Notes

  • MDN: marked Experimental — verify compatibility before production.
  • MDN: returns a Promise that fulfills with a boolean.
  • MDN: issuer must be a valid URL or you get TypeError.
  • MDN: secure context required; otherwise NotAllowedError.
  • MDN: at most two issuers per top-level origin.
  • Related: hasFocus(), getSelection(), hasRedemptionRecord().

Limited / Experimental Browser Support

Document.hasPrivateToken() is Experimental on MDN. Support is primarily Chromium-based (Chrome / Edge from 117+, Opera from 103+). Firefox and Safari currently lack support. Logos use the shared browser-image-sprite.png sprite from this project.

Experimental · Limited

Document.hasPrivateToken()

Promise-based check for a stored private state token from an issuer URL. Feature-detect before use.

Limited Not Baseline
Google Chrome 117+
Yes
Microsoft Edge 117+
Yes
Opera 103+
Yes
Mozilla Firefox Not supported
No
Apple Safari Not supported
No
Internet Explorer Not supported
No
hasPrivateToken() Partial

Bottom line: Use only with feature detection and a fallback. Prefer learning this API for privacy experiments; do not assume universal browser support.

Conclusion

document.hasPrivateToken(issuer) is an experimental instance method that resolves to whether a private state token from that issuer is already stored. Feature-detect, stay on HTTPS, pass a valid issuer URL, and treat support as limited.

Continue with hasFocus(), hasRedemptionRecord(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect before calling (experimental)
  • Pass absolute issuer URLs
  • Use HTTPS / localhost (secure context) (MDN)
  • Catch TypeError / NotAllowedError / InvalidStateError (MDN)
  • Check first, then request issuance only if needed (MDN)

❌ Don’t

  • Ship without a fallback on unsupported browsers
  • Ignore the two-issuer-per-origin limit (MDN)
  • Pass relative or invalid issuer strings
  • Assume Firefox/Safari support today
  • Treat this as a Baseline everyday DOM API

Key Takeaways

Knowledge Unlocked

Five things to remember about hasPrivateToken()

Experimental issuer token presence check.

5
Core concepts
🔄02

Arg

issuer URL

MDN
🎯03

Secure

HTTPS

required
04

Detect

typeof check

first
🛡05

Status

Experimental

MDN

❓ Frequently Asked Questions

MDN: Document.hasPrivateToken() returns a promise that fulfills with a boolean indicating whether the browser has a private state token stored from a particular issuer server.
MDN marks Document.hasPrivateToken() as Experimental. It is not Deprecated or Non-standard, but support is limited — check compatibility before production use.
MDN: issuer — a string representing the URL of an issuer server.
A boolean: true if a private state token from that issuer is stored; false otherwise (MDN).
MDN: InvalidStateError if the Document is not yet active; NotAllowedError if not in a secure context or the max issuers per top-level origin (two) is exceeded; TypeError if issuer is not a valid URL.
It is an instance method on Document (MDN page type). Call it as document.hasPrivateToken(issuer), and feature-detect with typeof document.hasPrivateToken === "function".
Did you know?

Private State Tokens grew out of the earlier “Trust Tokens” idea: prove that a browser completed an issuer check without sharing a long-lived cross-site identifier the way third-party cookies often did.

Next: hasRedemptionRecord()

Learn the experimental Private State Token check for whether a redemption record is already stored.

hasRedemptionRecord() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful