I've already added my scripts, but I wanted to know the preferred way.
I just put a <script> tag directly in the header.php of my template.

Is there a preferred method of inserting external or custom js files?
How would I bind a js file to a single page? (I have the home page in mind)

link|improve this question

67% accept rate
Great question! It's a very common one people ask and something that we definitely need to have well documented here. – MikeSchinkel Aug 19 '10 at 10:03
Also see wordpress.stackexchange.com/questions/575/… – naugtur Aug 23 '10 at 10:23
feedback

3 Answers

up vote 31 down vote accepted

Hi @naugtur:

Use wp_enqueue_script() in your theme

The basic answer is to use wp_enqueue_script() in an init hook, or if in the admin only then in an admin_menu or admin_init hook. It might look something like this (which assumes you are calling from your theme's functions.php file; note how I reference the stylesheet directory):

<?php
add_action('init', 'mysite_init');
function mysite_init() {
  $ss_url = get_bloginfo('stylesheet_directory')
  wp_enqueue_script('mysite-scripts',"$ss_url/js/mysite-scripts.js");
}

That's the basics.

Pre-defined and Multiple Dependent Scripts

But let's say you want to include both jQuery and jQuery UI Sortable from the list of default scripts included with WordPress and you want your script to depend on them? Easy, just include the first two scripts using the pre-defined handles defined in WordPress and for your script provide a 3rd parameter to wp_enqueue_script() which is an array of the script handles used by each script, like so:

<?php
add_action('init', 'mysite_init');
function mysite_init() {
  $ss_url = get_bloginfo('stylesheet_directory')
  wp_enqueue_script('jquery');
  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('mysite-scripts',"$ss_url/js/mysite-scripts.js",array('jquery','jquery-ui-sortable'));
}

Scripts in a Plugin

What if you want to do it in a plugin instead? Use the plugins_url() function to specify the URL of your Javascript file:

<?php
define('MY_PLUGIN_VERSION','2.0.1');
add_action('init','my_plugin_init');
function my_plugin_init() {
  wp_enqueue_script('jquery');
  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}

Versioning your Scripts

Also note that above we gave our plugin a version number and passed it as a 4th parameter to wp_enqueue_script(). The benefits of using script version number is that if multiple plugins or the theme enqueue the same script by version number more than once WordPress will only send one copy to the browser.

Load Scripts only on pages where needed

The 1st rule of Web Performance says to Minimize HTTP Requests so whenever possible you should limit the scripts to load only where needed. For example if you only need your script in the admin limit it to admin pages using the 'admin_init' hook instead:

<?php
define('MY_PLUGIN_VERSION','2.0.1');
add_action('admin_init','my_plugin_admin_init');
function my_plugin_admin_init() {
  wp_enqueue_script('jquery');
  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}

Load Your Scripts in the Footer

If your scripts is one of those that need to be loaded into the footer there is a 5th parameter of wp_enqueue_script() that tells WordPress to delay it and place it in the footer (assuming your theme did not misbehaved and that it indeed calls the wp_footer hook like all good WordPress themes should):

<?php
define('MY_PLUGIN_VERSION','2.0.1');
add_action('admin_init','my_plugin_admin_init');
function my_plugin_admin_init() {
  wp_enqueue_script('jquery');
  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION,true);
}

Finer Grained Control

If you need finer grained control than that Ozh has a great article entitled How To: Load Javascript With Your WordPress Plugin that details more.

Loading Scripts from Google's AJAX CDN

Assuming you are not familiar Google has a lot of the standard open-source libraries like jQuery hosted so that sites can load the files from Google and increase the likelihood that jQuery will already be in a visitor's browser's cache because so many other sites are loading jQuery from exactly the same location! To load jQuery from Google's AJAX CDN you'd need to use wp_deregister_script() and then wp_register_script() like so (note I'm using the latest version as of this writing even though Google will continue to host older versions):

<?php
define('MY_PLUGIN_VERSION','2.0.1');
add_action('admin_init','my_plugin_admin_init');
function my_plugin_admin_init() {
  wp_deregister_script('jquery');
  wp_register_script( 'jquery','http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js');
  wp_enqueue_script('jquery');
  wp_enqueue_script('jquery-ui-sortable');
  wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION,true);
}

Disabling Scripts to Gain Control

Justin Tadlock has a nice article entitled How to disable scripts and styles in case you want to:

  1. Combine multiple files into single files (mileage may vary with JavaScript here).
  2. Load the files only on the pages we’re using the script or style.
  3. Stop having to use !important in our style.css file to make simple CSS adjustments.

Passing Values from PHP to JS with wp_localize_script()

On his blog Vladimir Prelovac has a great article entitled Best practice for adding JavaScript code to WordPress plugins where he discusses using wp_localize_script() to allow you to set the value of variables in your server-side PHP to be later used in your client-side Javascript.

Really Fine Grained Control with wp_print_scripts()

And finally if you need really fine-grained control you can look into wp_print_scripts() as discussed on Beer Planet in a post entitled How To Include CSS and JavaScript Conditionally And Only When Needed By The Posts.

Epiloque

That's about it for Best Practices of including Javascript files with WordPress. If I missed something (which I probably have) be sure to let me know in the comments so I can add an update for future travelers.

link|improve this answer
That's an enormous article! Now I have a lot to choose ;) – naugtur Aug 19 '10 at 12:19
Nice response @mike! – Ben Everard Aug 19 '10 at 12:20
Ok, it worked. Now the second part of the question - how do I check if I'm on the homepage? – naugtur Aug 19 '10 at 13:39
Look for the answer here: wordpress.stackexchange.com/questions/575/… – naugtur Aug 23 '10 at 10:23
2  
Hook into admin_init instead of asking for is_admin(). Remove the version parameter if you use the Google CDN, otherwise the browser cache will hold two versions: one without the query string from other sites and your's. – toscho Nov 9 '10 at 23:02
show 6 more comments
feedback

To compliment Mikes wonderful illustration of using enqueues i just wish to point out that scripts included as dependancies do not necessarily need to be enqueued...

I'll use the Scripts in a Plugin code from Mikes answer as an example..

define('MY_PLUGIN_VERSION','2.0.1');
add_action('init','my_plugin_init');
function my_plugin_init() {
   wp_enqueue_script('jquery');
   wp_enqueue_script('jquery-ui-sortable');
   wp_enqueue_script('my-script',plugins_url('/js/my-script.js',__FILE__),array('jquery','jquery-ui-sortable'),MY_PLUGIN_VERSION);
}

This can be trimmed down to read..

define('MY_PLUGIN_VERSION','2.0.1');
add_action('init','my_plugin_init');
function my_plugin_init() {
   wp_enqueue_script('my-script', plugins_url( '/js/my-script.js', __FILE__ ), array('jquery','jquery-ui-sortable'), MY_PLUGIN_VERSION);
}

Declaring dependancies will result in those scripts being enqueued for you, so you don't actually need to enqueue them manually if you're setting them as a dependancy for another script..

EDIT: Additionally, there may be users wondering if setting a multiple dependancies might cause scripts(that are dependant on one another) to wrongly queue.

For example:

wp_enqueue_script('example-script-1','example/path/example_script_1.js',array('example-script-2','example-script-3') );

If script 2 were dependant on script 3(ie. script 3 should load first), this wouldn't matter, WordPress would still run enqueues for both and figure out which needs to run first, loading a script as a dependancy will not screw with any existing dependancies of the scripts being called(it all gets worked out automagically for you).

link|improve this answer
feedback

Take a look at my question from a few days ago, the answer to part of your question is there:

link|improve this answer
Thx. I saw that already, but it didn't cover my question fully. – naugtur Aug 19 '10 at 12:18
That's ok, I knew it wouldn't answer all of your question but for people surfing in in the future there's a reference to the other post :-) – Ben Everard Aug 19 '10 at 12:20
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.