Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 44 of 45

jQuery in WordPress and noConflict mode

Use jQuery in WordPress themes and plugins the right way, with wp_enqueue_script dependencies, noConflict mode, safe $ wrappers and passing data from PHP.

12 minjQuery todayUpdated 23 October 2026

By the end of this lessonLoad your scripts after WordPress's own jQuery, write code that works in noConflict mode, and pass settings from PHP to JavaScript safely.

jQuery is already there

WordPress includes its own copy of jQuery, and the admin area, many themes and many plugins depend on it. WordPress upgrades that copy on its own schedule, so check which version a site runs with jQuery.fn.jquery in the browser console before relying on jQuery 4 behaviour.

The golden rule: do not add a second copy. Loading another jQuery from a CDN in your theme's header can break plugins that attached themselves to the first one, and wastes bandwidth.

Loading your script properly

In a theme's functions.php (or a plugin), register your script with wp_enqueue_script and list jquery as a dependency:

php
<?php
add_action('wp_enqueue_scripts', function () {
    wp_enqueue_script(
        'mytheme-site',                                   // a unique handle
        get_template_directory_uri() . '/js/site.js',     // the file
        ['jquery'],                                       // load WordPress's jQuery first
        '1.0.0',                                          // version, for cache busting
        ['in_footer' => true]                             // load before </body>
    );
});

WordPress then prints jQuery once, followed by your file, in the right order, on every front-end page. Use the admin_enqueue_scripts hook for scripts in the admin area.

noConflict mode: where is $?

WordPress loads jQuery in noConflict mode, so the short name $ is not jQuery, because other libraries may want it. Code copied from a normal tutorial fails:

html
<p class="note">Hello</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>jQuery.noConflict();</script>
<script>
  $(".note").text("Changed");     // what most tutorials show
</script>
result
Hello
TypeError: $ is not a function

jQuery.noConflict() gives $ back to whatever owned it before jQuery loaded; here, nothing. The full name jQuery still works everywhere.

Getting $ back safely

You do not have to type jQuery all the time. Two patterns give you a private $ that means jQuery:

html
<p class="note">Hello</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>jQuery.noConflict();</script>
<script>
  // 1. Document ready that receives $ (the most common in WordPress themes)
  jQuery(function ($) {
    $(".note").text("Changed with $ inside the ready function");
    console.log("ready wrapper:", $(".note").text());
  });

  // 2. An immediately invoked function, for code that does not need to wait
  (function ($) {
    console.log("IIFE wrapper: $ is jQuery?", $ === jQuery, "| version", $.fn.jquery);
  })(jQuery);

  console.log("outside, $ is", typeof $);
</script>
result
IIFE wrapper: $ is jQuery? true | version 4.0.0
outside, $ is undefined
ready wrapper: Changed with $ inside the ready function

Inside each wrapper, $ is a parameter that receives jQuery, so it does not matter what $ means elsewhere. Wrap all of your theme's jQuery code in one of these.

Living with another library

noConflict exists because jQuery is not the only library that likes $. Here an older library has already taken $ before jQuery loads:

html
<script>
  // Pretend another library defined $ first
  window.$ = function () { return "other library"; };
</script>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log("after loading jQuery, $ is jQuery?", $ === jQuery);
  const jq = jQuery.noConflict();
  console.log("after noConflict, $() returns:", $());
  console.log("jQuery still works as jq: version", jq.fn.jquery);
</script>
result
after loading jQuery, $ is jQuery? true
after noConflict, $() returns: other library
jQuery still works as jq: version 4.0.0

noConflict() returned the other library's $ and handed back jQuery itself, which you can store under any name you like.

Passing data from PHP

Scripts often need values that only PHP knows: the Ajax URL, a security nonce, translated text. Do not echo PHP values into a script tag by hand; attach them to your script with WordPress's functions, which escape them properly:

php
<?php
wp_enqueue_script('mytheme-site', get_template_directory_uri() . '/js/site.js', ['jquery'], '1.0.0', true);

wp_add_inline_script('mytheme-site', 'const mythemeSettings = ' . wp_json_encode([
    'ajaxUrl' => admin_url('admin-ajax.php'),
    'nonce'   => wp_create_nonce('mytheme_like'),
    'labels'  => ['liked' => __('Liked!', 'mytheme')],
]) . ';', 'before');

Then use it from your jQuery code:

javascript
jQuery(function ($) {
  $(".like-button").on("click", function () {
    const $btn = $(this);
    $.post(mythemeSettings.ajaxUrl, {
      action: "mytheme_like",
      nonce: mythemeSettings.nonce,
      post_id: $btn.data("postId")
    }).done(() => $btn.text(mythemeSettings.labels.liked));
  });
});

On the PHP side, the wp_ajax_mytheme_like hook handles the request, and it must check the nonce with check_ajax_referer('mytheme_like', 'nonce') before doing anything. The older wp_localize_script() function is also widely used for passing data this way. The PHP course covers the server side of handling requests safely.

Tips for WordPress sites

  • Use the WordPress copy of jQuery, never deregister it to load another version unless you have tested every plugin with that version.
  • Load scripts in the footer and only on the pages that need them (check is_page(), is_singular() and similar before enqueueing).
  • Use delegation for content that page builders and plugins add after load.
  • Prefix everything: handles, global variables, custom events and CSS classes, so your theme never clashes with a plugin.

Common mistakes

  • Adding jQuery from a CDN in header.php alongside WordPress's copy.
  • Using $ outside a wrapper, which fails in noConflict mode.
  • Printing PHP values into JavaScript by hand, which breaks on quotes and can open XSS holes.
  • Skipping the nonce check on Ajax handlers.

Exercise

Write theme code that, on document ready, adds the class has-js to the html element and logs the number of links in the main menu (#primary-menu a). It must work in noConflict mode.

Show one possible answer
html
<ul id="primary-menu"><li><a href="/">Home</a></li><li><a href="/blog/">Blog</a></li></ul>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>jQuery.noConflict();</script>
<script>
  jQuery(function ($) {
    $("html").addClass("has-js");
    console.log($("#primary-menu a").length, "menu links");
  });
</script>
result
2 menu links

Key points

  • WordPress ships its own copy of jQuery; load it with wp_enqueue_script and a 'jquery' dependency instead of adding another copy.
  • WordPress runs jQuery in noConflict mode, so $ is not jQuery by default; use jQuery or a wrapper that receives $.
  • jQuery(function ($) { ... }) runs on document ready and gives you a safe $ inside.
  • Pass data from PHP with wp_add_inline_script or wp_localize_script, and escape it; never print PHP values into JavaScript by hand.

Check yourself

1. In a WordPress theme, why does $(".menu") fail with "$ is not a function"?
2. How should a theme load a script that needs jQuery?
3. What does jQuery.noConflict() do?
4. What is the safe way to pass a PHP setting to your script?