Skip to main content

no-dom-globals-in-constructor

Disallow browser-only globals during class construction.

Targeted pattern scope

This rule targets constructor bodies, constructor parameter defaults, instance field initializers, and immediately invoked functions in those locations.

What this rule reports

It reports unguarded browser-global references that execute when a class instance is created.

Why this rule exists

Constructors and instance field initializers can run during server-side rendering. Browser-only global access in either location can therefore crash an SSR request.

❌ Incorrect

class Viewport {
width = window.innerWidth;

constructor() {
this.title = document.title;
}
}

✅ Correct

class Viewport {
constructor() {
const hasWindow = typeof globalThis.window !== "undefined";
if (hasWindow) {
this.width = globalThis.window.innerWidth;
}
}
}

Constructor parameter defaults and immediately invoked functions are checked. Deferred callbacks, static fields, guarded accesses, shadowed locals, and type-only references are not reported. Guards may use direct or globalThis typeof comparisons, "name" in globalThis, or a predicate stored in a single const binding. Mutable or shadowed predicates are intentionally not trusted. Shared scope, guard, JSX, and execution results are cached per linted file.

Behavior and migration notes

Review each finding manually and move the access to a client-only lifecycle or guarded path; this rule does not autofix.

ESLint flat config example

import etcMisc from "eslint-plugin-etc-misc";

export default [
{
plugins: { "etc-misc": etcMisc },
rules: { "etc-misc/no-dom-globals-in-constructor": "error" },
},
];

When not to use it

Disable this rule for classes that are provably instantiated only in a browser. The rule reports only because moving initialization can change lifecycle semantics.

Package documentation

Rule catalog ID: R031

Further reading

This is a modern lexical-scope rewrite inspired by eslint-plugin-ssr-friendly.

Adoption resources

  • Start at warning level in CI, then move to error after cleanup.
  • Review each finding against constructor and field-initialization order.