Any web developer who has dabbled with JavaScript and jQuery has probably encountered the dreaded “jQuery is not defined” error. It’s confusing, frustrating, and, fortunately, almost always fixable. The key typically lies in understanding load order, the use of defer and async script attributes, and ensuring compatibility with other scripts or content delivery networks (CDNs). Mastering these concepts not only resolves this common error but also builds your confidence in managing scripts efficiently in any web project.
TL;DR
The “jQuery is not defined” error usually appears when your JavaScript code is trying to use jQuery before it’s loaded. This can happen due to incorrect script load order, improper use of defer or async, or a CDN failing to load. To fix it, ensure jQuery is loaded before any scripts that depend on it, use defer wisely, and provide fallbacks if you’re using a CDN. Understanding these key elements ensures more stable and bug-free web pages.
What Does “jQuery is Not Defined” Really Mean?
When a browser throws a “jQuery is not defined” error, it’s telling you that your JavaScript code is trying to use jQuery functions before the jQuery library has finished loading. In simple terms, your code is saying: “I want to use jQuery,” but the browser doesn’t know what that is—because the library isn’t available yet.
This typically happens for the following reasons:
- jQuery was never loaded.
- There’s a typo in the script URL.
- The browser blocked the jQuery script (e.g., due to mixed content or CORS errors).
- Your script that uses jQuery runs before jQuery is available in the DOM.
The Importance of Load Order
Web pages load scripts in the order you tell them to, unless certain attributes change that behavior. That’s why load order is crucial. Consider this example:
<script src="myscript.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
Here, myscript.js is loaded first—but if it relies on jQuery, it will throw an error because, at that moment, jQuery hasn’t been defined. The solution? Flip the order:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="myscript.js"></script>
This ensures jQuery is available before anything tries to use it.
Defer, Async, and Their Pitfalls
Modern HTML offers ways to optimize the loading of scripts using defer and async. However, misusing these can lead to your jQuery-dependent scripts firing too early.
- Async: This attribute tells the browser to download the script in the background and execute it as soon as it’s ready. The execution order is not guaranteed.
- Defer: Similar to async in downloading, but defer ensures scripts run in the order they appear and only after the document has been parsed.
If you’re using defer, be mindful of the order:
<script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
<script src="myscript.js" defer></script>
This is valid and will work because both scripts will be executed in order and only after the DOM is ready. But using async like this:
<script src="https://code.jquery.com/jquery-3.6.0.min.js" async></script>
<script src="myscript.js" async></script>
could cause problems. There’s no guarantee that jQuery will be available before myscript.js runs.
Common Scenarios That Cause This Error
Let’s break it down further with some real-life examples of how this error can creep in:
1. CDN Fails to Load
If you’re using jQuery from a CDN like Google or jQuery’s official one, there’s always the risk that the resource might not load—due to network errors, firewall blocks, or misconfigured URLs.
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
If the source above fails and you’re not checking for that failure, your dependent scripts will break.
2. jQuery Loaded at the Bottom
Sometimes developers place all scripts at the bottom of the HTML just before </body> for performance reasons. But if your inline script appears in the <head> or earlier in the DOM, and you’re trying to access jQuery there, it’s not yet available.
3. Wrong jQuery Path
Perhaps you’re hosting jQuery locally and have a typo in your path:
<script src="/js/jquerry.js"></script>
This tiny typo might cost you hours of debugging unless you verify with browser dev tools that the file is actually loading.
Best Practices to Avoid the Error
Now that we understand the causes, here are some tips to make sure you never see “jQuery is not defined” again:
- Always load jQuery first before any scripts that depend on it.
- Use the
deferattribute wisely to maintain order but reduce blocking during page load. - Provide fallbacks when using CDNs:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
if (typeof jQuery === 'undefined') {
document.write('<script src="/local/path/to/jquery.min.js"><\/script>');
}
</script>
This will load a local fallback if the CDN fails.
jQuery in Modern Development
In the world of ES6, React, Vue, and component-based architecture, jQuery isn’t as essential as it once was. But many legacy systems still rely on it, and you might still be maintaining or developing for environments where it’s heavily used.
If you’re integrating jQuery into an environment that uses module bundlers (like Webpack), you can define jQuery as a dependency explicitly:
// In your webpack.config.js
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
Or via ES6 imports:
import $ from 'jquery';
Debugging Checklist
If you’re facing the “jQuery is not defined” error, walk through this quick checklist:
- Did the jQuery script actually load? (Check DevTools > Network tab)
- Is your code executing before jQuery is loaded?
- Are you using
asyncwithout understanding its implications? - Is the CDN reachable from your environment?
- Are multiple jQuery versions conflicting with each other?
Conclusion
Assuming jQuery “just works” can lead to wasted hours debugging avoidable issues. Most instances of the “jQuery is not defined” error boil down to load order mishaps, improper script attributes, or external dependencies like CDNs going offline.
By being mindful of when and how your scripts load—as well as what scripts they depend on—you can ensure smoother execution and deliver a better overall user experience. Whether you’re building new functionality on a legacy system or integrating jQuery into a modern workflow, keeping these fundamentals in mind will help you maintain cleaner, more reliable code.