dotnet/AspNetCore.Docs · error · Error

jQuery requires a window with a document

Error message

jQuery requires a window with a document

What it means

jQuery's CommonJS branch returns a factory `function(w) { if (!w.document) throw ... }` when `global.document` is absent (e.g. Node.js). The factory is invoked with a `window`; if that window has no document, jQuery cannot manipulate the DOM and throws.

Source

Thrown at aspnetcore/mvc/views/tag-helpers/th-components/samples/RazorPagesSample/wwwroot/lib/jquery/jquery.js:29

 *
 * Date: 2016-01-08T20:02Z
 */

(function( global, factory ) {

	if ( typeof module === "object" && typeof module.exports === "object" ) {
		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

// Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
//"use strict";
var arr = [];

var document = window.document;

View on GitHub (pinned to c67a80103a)

Solutions

  1. Provide a real DOM via jsdom: `const { JSDOM } = require('jsdom'); const dom = new JSDOM(''); const $ = require('jquery')(dom.window);`.
  2. Avoid requiring jQuery on the server; isolate DOM manipulation to the browser bundle.
  3. Pass the full window object, not a partial mock: ensure `.document` exists before invoking the factory.

Example fix

// before (Node, no window)
const $ = require('jquery');

// after (jsdom provides window + document)
const { JSDOM } = require('jsdom');
const dom = new JSDOM('');
const $ = require('jquery')(dom.window);
Defensive patterns

Strategy: validation

Validate before calling

function loadJQuery(windowLike) {
  if (!windowLike || !windowLike.document) {
    throw new Error('Provide a window with a document (use jsdom in Node)');
  }
  return require('jquery')(windowLike);
}

Type guard

function hasDocument(w) {
  return w != null && typeof w.document !== 'undefined';
}

Try / catch

let $;
try {
  const { JSDOM } = require('jsdom');
  $ = require('jquery')(new JSDOM('').window);
} catch (e) {
  if (/window with a document/.test(e.message)) throw new Error('Install jsdom for server-side jQuery');
  throw e;
}

Prevention

When it happens

Trigger: Calling `require('jquery')(someWindow)` where `someWindow.document` is undefined; or `require('jquery')` in pure Node with no window at all triggers the factory path. Often seen in server-side rendering or test environments.

Common situations: Running jQuery-dependent code in Node during SSR or unit tests without jsdom; passing a minimal mock window that lacks document; importing a browser bundle into a Node test runner.

Related errors


AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13). Data as JSON: /api/errors/79e8e7368763c6de. Report an issue: GitHub.