Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
VGSOURCES
Get listed

JavaScriptPATCH 2026.10.16

How to Add jQuery to a WordPress Theme (Safely and the WordPress Way)

By VGSources Team 10 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The supported way to add jQuery to a WordPress theme is to enqueue your script from functions.php on the wp_enqueue_scripts hook, declare WordPress’s registered jquery handle as a dependency, and write your JavaScript for noConflict() mode. This gives WordPress control over load order, avoids duplicate libraries, and prevents the common “$ is not defined” error.

What you are adding—and why the method matters

A theme usually needs two separate pieces: the jQuery library and your theme’s own JavaScript file. WordPress already registers a jQuery library, so your theme normally should not download or register another copy. Instead, your file declares that it depends on the registered handle named jquery.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

WordPress then builds the correct dependency order: jQuery is printed before your dependent file, and your file is printed only once even if another component also requests it. The API function for this is wp_enqueue_script(), called from the front-end wp_enqueue_scripts action. Hardcoding a <script> element in header.php bypasses that dependency system and can produce duplicate libraries, incorrect ordering, or conflicts with plugins.

The examples below assume a classic PHP theme. A child theme must use a URL helper that points to the directory where the JavaScript file actually exists.

Recommended implementation in functions.php

1. Create the JavaScript file

For the example, create assets/js/main.js inside the theme that is active on the site. If the file belongs to a child theme, place it in the child-theme directory; if it belongs to the parent, place it in the parent directory and use the corresponding URI helper.

2. Enqueue it on the front end

Add this code to the active theme’s functions.php:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
function mytheme_enqueue_scripts() {
    wp_enqueue_script(
        'mytheme-main',
        get_parent_theme_file_uri( 'assets/js/main.js' ),
        array( 'jquery' ),
        wp_get_theme()->get( 'Version' ),
        array(
            'in_footer' => true,
        )
    );
}

Each argument has a job:

  • mytheme-main: a unique handle for your script. Use a theme-specific prefix so it does not collide with a plugin or another theme.
  • get_parent_theme_file_uri( 'assets/js/main.js' ): builds the URL to a file in the parent theme. For a file in a child theme, use get_theme_file_uri( 'assets/js/main.js' ) when that matches the location in your theme setup.
  • array( 'jquery' ): declares the registered WordPress jQuery handle as a dependency. WordPress resolves this handle before mytheme-main.
  • wp_get_theme()->get( 'Version' ): uses the active theme version as the script version, helping browsers recognize a changed asset after a theme update.
  • array( 'in_footer' => true ): asks WordPress to print the script in the footer rather than in the document head.

Use a different handle and function prefix for each theme. The handle is an internal identifier, not the filename, and changing the filename alone does not make a handle unique.

3. Confirm that the theme has the required template hooks

The active theme must call wp_head() in its head template and wp_footer() immediately before the closing body tag. WordPress uses those locations to print enqueued assets. Very old or heavily customized themes that omit either call may appear to accept the enqueue code while outputting no script tag.

Make the $ alias work in WordPress

WordPress loads its bundled jQuery in noConflict() mode. That means the global $ alias is not available in the way it is on a standalone jQuery page. Calling $( '.menu-toggle' ) at global scope can therefore produce “$ is not defined” or “$ is not a function.”

Use the theme handbook’s wrapper pattern

Wrap the file in an immediately invoked function expression (IIFE), accept jQuery as the argument, and use $ only inside that function:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
( function( $ ) {
    $( function() {
        $( '.menu-toggle' ).on( 'click', function() {
            $( '.site-navigation' ).toggleClass( 'is-open' );
        } );
    } );
} )( jQuery );

The outer function creates a local $ variable. The final )( jQuery ) passes WordPress’s global jQuery object into that local parameter. The inner callback waits until the document is ready before looking for the button and navigation elements.

Use the ready callback’s local parameter instead

This equivalent form keeps the alias local to the ready callback:

jQuery( document ).ready( function( $ ) {
    $( '.menu-toggle' ).on( 'click', function() {
        $( '.site-navigation' ).toggleClass( 'is-open' );
    } );
} );

Both patterns are safe. The important rule is not to assume that $ is globally available in a WordPress theme.

How WordPress decides script order

When you pass array( 'jquery' ) as the dependency list, you are declaring a relationship rather than manually arranging tags. WordPress knows that your handle requires the registered jquery handle and resolves that dependency before printing your script. If another enqueued script also depends on jQuery, WordPress can share the same registered library instead of adding another copy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Approach What happens Typical result
Enqueue with array( 'jquery' ) WordPress resolves the registered dependency and prints the files in dependency order. Preferred for theme code; compatible with other enqueued assets.
Hardcoded tag in header.php The browser sees a tag, but WordPress does not know the relationship or handle. Possible ordering errors, duplicate libraries, and harder maintenance.
Manual second jQuery copy A theme loads a separate library in addition to the registered one. Potential plugin conflicts, different versions, and two competing jQuery objects.
Global $ usage Code assumes the standalone jQuery alias exists. “$ is not defined” or “$ is not a function” in WordPress.
IIFE or ready-callback wrapper $ is mapped to the global jQuery object only inside a local scope. Works with WordPress’s noConflict() behavior.

Choosing the correct theme URL helper

The URL must match the theme directory that contains the file. A wrong helper can produce a valid-looking URL that returns a 404.

  • Parent-theme file: get_parent_theme_file_uri( 'assets/js/main.js' ).
  • Active-theme file: get_theme_file_uri( 'assets/js/main.js' ) when the file should resolve from the active theme, including a child theme where appropriate.
  • Child-theme-specific file: use a child-theme URI helper available in your theme’s setup, or construct the URL from the child stylesheet directory when that is how the theme organizes assets.

Do not mix a parent URL helper with a file that exists only in the child directory. In browser developer tools, open the generated script URL directly; a 404 confirms a path or directory mismatch rather than a jQuery problem.

Footer, defer, and async options

The fifth argument to wp_enqueue_script() can be an arguments array. WordPress 6.3 and later document options including in_footer and a loading strategy.

Conservative footer loading

The example’s in_footer => true is the safest general starting point for a theme script. It keeps the script out of the head while preserving the dependency relationship.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Adding defer

If the script and its dependencies do not require immediate execution during parsing, you can request deferred loading:

wp_enqueue_script(
    'mytheme-main',
    get_parent_theme_file_uri( 'assets/js/main.js' ),
    array( 'jquery' ),
    wp_get_theme()->get( 'Version' ),
    array(
        'in_footer' => true,
        'strategy'   => 'defer',
    )
);

Test this change with every feature that depends on the script. A loading strategy can expose assumptions about execution timing, inline scripts, or code that expects a library to be ready during parsing.

Why async needs more caution

async allows a script to execute as soon as it finishes downloading, so execution order is not guaranteed. That is a poor fit for a file that depends on jQuery or for code whose behavior depends on another script. Use it only when the script is genuinely independent and you have verified that no ordering relationship is required.

Bundled jQuery versus loading a custom copy

The WordPress Theme Handbook advises themes not to replace a library that WordPress already bundles. The registered jquery handle is the integration point expected by themes and plugins. Reusing it means other components can share the same dependency and reduces the chance that two versions will attach different behavior to the page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Decision Use the bundled handle when… Consider another architecture only when…
Library source Your code needs ordinary jQuery APIs and no special build requirement. A documented compatibility constraint requires a separate, isolated implementation.
Version management You want WordPress and its ecosystem to manage the registered library. You control every dependent script and have a tested reason to pin a different library.
Conflict risk You want to avoid duplicate jQuery objects and plugin incompatibilities. You have an explicit isolation strategy and have tested it with the active plugins.

Do not add a second CDN or theme-local jQuery file merely because it is familiar from a non-WordPress project. If you need behavior that the bundled version does not provide, document the compatibility requirement and test the complete site rather than silently replacing the registered handle.

Conditional loading for a smaller front end

You do not have to load every theme script on every URL. Keep the dependency declaration, but enqueue the file only where its feature exists. For example, a script used by a template-specific gallery can be wrapped in a conditional such as is_page_template(), an existing page check, or a post-type check that matches your site.

add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_gallery' );
function mytheme_enqueue_gallery() {
    if ( ! is_page_template( 'templates/gallery.php' ) ) {
        return;
    }

    wp_enqueue_script(
        'mytheme-gallery',
        get_theme_file_uri( 'assets/js/gallery.js' ),
        array( 'jquery' ),
        wp_get_theme()->get( 'Version' ),
        array( 'in_footer' => true )
    );
}

The condition must run on the front-end enqueue hook, where WordPress’s query context is available. Keep the handle unique even when several conditional scripts are defined in the same function file.

Complete setup checklist

  • The file exists under the active parent or child theme directory.
  • The enqueue callback is attached to wp_enqueue_scripts, not an admin-only hook.
  • The handle is unique and appears only once in your theme code.
  • The URL helper points to the directory that actually contains the file.
  • array( 'jquery' ) is present when the file calls jQuery.
  • Your JavaScript uses jQuery directly or maps it to a local $ with an IIFE or ready callback.
  • The active theme calls both wp_head() and wp_footer().
  • The browser can load the generated file without a 404.
  • Any optimization, caching, concatenation, delay, or minification layer has been tested with the new dependency.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

“$ is not defined”

This means the code is trying to use the shorthand outside a safe local scope, or jQuery did not load at all. First inspect the page source or Network panel to see whether the WordPress jQuery file is present. If it is present, change the file to the IIFE or ready-callback pattern and ensure the enqueue dependency is array( 'jquery' ).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“jQuery is not defined”

The library itself is unavailable when your file executes. Check that the enqueue callback runs, that the handle is spelled exactly jquery, and that no optimization tool has reordered or removed the dependency. A theme or plugin that deregisters jQuery can also cause this symptom; identify that change before adding a duplicate library.

“$ is not a function”

In WordPress this often means $ refers to something other than jQuery, or the alias is being used outside the wrapper. Use jQuery at the boundary and a local $ inside the callback. Also check for a JavaScript syntax error earlier in the page that prevented initialization.

The script URL returns 404

Compare the generated URL with the real directory and filename, including capitalization. Parent and child theme paths are different. Correct the URI helper or move the file to the directory represented by the helper; do not try to solve a path error by changing jQuery code.

The file never appears in the HTML

Verify that the function is in the active theme’s functions.php, that the action name is exactly wp_enqueue_scripts, and that the template prints wp_head() and wp_footer(). If a conditional surrounds the enqueue call, temporarily remove the condition to determine whether the condition is excluding the current URL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

It worked until a cache or optimization change

Optimization layers can concatenate, delay, defer, or reorder scripts. Inspect the final generated markup and console errors rather than only the original PHP. Exclude the dependent pair from an optimization rule temporarily, then re-enable settings one at a time while preserving the declared dependency.

Practical debugging workflow

  1. Open the page in a private browser window with caches cleared.
  2. In developer tools, check the Console for jQuery is not defined, $ is not a function, syntax errors, and the first failing line.
  3. In the Network panel, filter for JavaScript and confirm that the jQuery request and your theme file both load successfully.
  4. Open your theme file’s response and verify that it is the expected JavaScript rather than an HTML error page.
  5. Inspect the final document or page source to confirm that the dependency is printed before the dependent script.
  6. Disable script optimization or delay features briefly. If the error disappears, restore the feature and add a dependency-aware exclusion or configuration.
  7. Test logged-out and logged-in views, because admin-bar markup, permissions, and conditional templates can change the page context.

When jQuery is the wrong tool

Adding jQuery is appropriate when the theme feature or an existing WordPress-compatible component requires it. For a small interaction, modern browser APIs can avoid a library dependency altogether, but that is a design decision rather than a reason to load a second jQuery copy. If you do use jQuery, follow WordPress’s registered-handle and noConflict() conventions so your code coexists with the rest of the site.

Final implementation reference

Use this compact pair as a known-good baseline, then adapt the selector and URL to your theme.

<?php
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
function mytheme_enqueue_scripts() {
    wp_enqueue_script(
        'mytheme-main',
        get_parent_theme_file_uri( 'assets/js/main.js' ),
        array( 'jquery' ),
        wp_get_theme()->get( 'Version' ),
        array( 'in_footer' => true )
    );
}
( function( $ ) {
    $( function() {
        $( '.menu-toggle' ).on( 'click', function() {
            $( '.site-navigation' ).toggleClass( 'is-open' );
        } );
    } );
} )( jQuery );

This arrangement expresses the dependency, respects WordPress’s jQuery mode, and leaves WordPress in charge of printing and ordering the scripts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

JavaScriptjQueryWordPressWordPress themeswp_enqueue_script

Leave a reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.