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.