WordPress $ is not defined

If you copy a normal jQuery snippet into a WordPress theme or plugin, sooner or later you hit Uncaught ReferenceError: $ is not defined. The confusing part is that jQuery itself is loaded; your other jQuery code may even be working. So why does $ blow up?

Why It Happens

WordPress ships its own copy of jQuery and loads it in no-conflict mode. On startup it effectively runs:

jQuery.noConflict();

noConflict() tells jQuery to give back control of the global $. After it runs, jQuery still points to the library, but $ no longer does; it is left free for some other library to claim.

WordPress does this on purpose. A page can pull in scripts from the core, your theme, and any number of plugins, and several of those libraries historically also wanted $ as their own shorthand. Releasing $ is how WordPress keeps them from stepping on each other. The cost is that your $ is gone unless you ask for it back.

There are two ways to deal with this.

Option 1: Just Use jQuery

The simplest fix is to stop relying on the shorthand and spell out jQuery everywhere:

jQuery(document).ready(function () {
    jQuery("#selector").doSomething();
});

This always works because jQuery is never released. The downside is that it gets noisy fast: every $ in a longer script becomes jQuery.

Option 2: Reclaim $ in a Local Scope

The cleaner approach is to get $ back inside your own scope without touching the global one. Wrap your code in a function that receives jQuery as its $ argument:

(function ($) {
    // $ is the local jQuery here, the global stays untouched
    $("#selector").doSomething();
})(jQuery);

If you also need to wait for the DOM, jQuery’s ready handler passes itself as the first argument, so you get $ and document-ready timing in one step:

jQuery(function ($) {
    // runs on document ready, with $ available
    $("#selector").doSomething();
});

Which One Should You Use?

  • A throwaway snippet? Use jQuery directly (Option 1) and move on.
  • A theme or plugin? Use the wrapper (Option 2). You keep the familiar $, your code reads like ordinary jQuery, and you never re-pollute the global namespace, which is exactly the conflict WordPress was trying to avoid in the first place.

References