One of the challenges you will run into, when developing for WordPress, is finding a way to make your data (which is accessed via PHP) available to your scripts. For example, you might have a popup notification that is displayed when someone clicks a button. The message in this popup, in order to be translatable, should be defined via PHP. The question then, is how do you get it into your jQuery? The answer is with the truly awesome wp_localize_script() function.

The wp_localize_script() was one that eluded me for my first two years of WordPress development. I would see references to it, but I couldn’t ever figure out exactly what it did, or how it worked. It wasn’t until I read Michael Martin’s tutorial titled Load Next WordPress Posts With AJAX. He was the first person I had come across that really explained, and demonstrated how the function worked, and what it did.

The gist of the function is that it allows you to take data from PHP and make it available to your Javascript.

Let’s take the example I mentioned a moment ago, with the popup alert, and see how we can use wp_localize_script().

Since we are loading our scripts correctly, we are using wp_enqueue_script() to load our jQuery:

1
2
3
4
5
6
7
<?php
function pw_load_scripts() {
 
	wp_enqueue_script('pw-script', plugin_dir_url( __FILE__ ) . 'js/pw-script.js');
 
}
add_action('wp_enqueue_scripts', 'pw_load_scripts');

The use of wp_enqueue_script() or wp_register_script() is required for wp_localize_script() to work.

Our example jQuery file looks like this:

1
2
3
4
5
jQuery(document).read(function($) {
	$('#pw_button').on('click', function() {
		alert('Hey! You have clicked the button!');
	});
});

These two code snippets assume that we have an HTML button somewhere on our page with an ID of “pw_button”. When that button is clicked, a javascript alert is displayed, like the one below:

The problem that we have here is that our text, “Hey! You have clicked the button!”, is hard coded into our jQuery. Why is this bad? It’s bad because it cannot be translated, but we can get around this by using wp_localize_script().

Usage of the function is actually quite simple. Here is our PHP:

1
2
3
4
5
6
7
8
9
10
11
<?php
function pw_load_scripts() {
 
	wp_enqueue_script('pw-script', plugin_dir_url( __FILE__ ) . 'js/pw-script.js');
	wp_localize_script('pw-script', 'pw_script_vars', array(
			'alert' => __('Hey! You have clicked the button!', 'pippin')
		)
	);
 
}
add_action('wp_enqueue_scripts', 'pw_load_scripts');

The first function parameter is the handle of our Javascript file, which is the same as the first parameter in our wp_enqueue_script() function.

The function is going to create an object that is accessible from our Javascript The name of this object is the second parameter, pw_script_vars

The third function parameter, is an array of variables to pass to our script. Each key in the array will be setup as an item in our Javascript object. In this case, I have only passed one array key, so we will have just one option, but you can have as many as you want. Each variable will be accessible like this:

pw_script_vars.VARIABLE_NAME

Our alert text is accessible like this:

pw_script_vars.alert

If this doesn’t make sense, read just a little further and it will.

Previously, in our jQuery, we hard coded the alert message, but now we can just pass our localized variable, like so:

1
2
3
4
5
jQuery(document).read(function($) {
	$('#pw_button').on('click', function() {
		alert( pw_script_vars.alert );
	});
});

That is really, really cool, if you ask me.

Now what about multiple variables? let’s say, for a moment, that our jQuery contains two alerts, one for each button that is pressed. Because we have two buttons, we want to have two messages, and wp_localize_script() makes this very easy:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
function pw_load_scripts() {
 
	wp_enqueue_script('pw-script', plugin_dir_url( __FILE__ ) . 'js/pw-script.js');
	wp_localize_script('pw-script', 'pw_script_vars', array(
			'alert' => __('Hey! You have clicked the button!', 'pippin'),
			'message' => __('You have clicked the other button. Good job!', 'pippin')
		)
	);
 
}
add_action('wp_enqueue_scripts', 'pw_load_scripts');

Our updated jQuery now looks like this:

1
2
3
4
5
6
7
8
9
10
11
jQuery(document).read(function($) {
 
	$('#pw_button').on('click', function() {
		alert( pw_script_vars.alert );
	});
 
	$('#pw_button_2').on('click', function() {
		alert( pw_script_vars.message );
	});
 
});

Is this the first time you’ve seen wp_localize_script()? Do you have questions? Just let me know below in the comments.

  1. Paul

    yeah, it’s a great technique. I’m using it heavily on a plugin I’m working on. I use it with json_encode, and then jQuery parseJSON to use WordPress settings as objects..
    didn’t know about the array for passing multiple variables though. that’s a nice tip

    • Pippin

      Oh, that’s a great idea for passing plugin settings.

      I use it most commonly for passing the admin ajax URL to my JS.

  2. Michael Martin

    Great post Pippin. It’s really good to see this technique explained fully. It’s not something you come across easily, but once you’ve tried it out, you start to wonder how you ever did without it before.

    And thank you for the post link! πŸ˜€

    • Pippin

      I can’t imagine not using this function in just about every plugin I write.

      Thanks for stopping by πŸ™‚

  3. Gerasimos

    wp_localize_script() is a powerful little thing. We usually use it to pass parameters from our options panel to jQuery sliders mostly located on homepages.

  4. WPexplorer

    Glad you wrote about it πŸ˜‰

  5. karthi

    Thanks!! it’s simple to understand:-)

  6. Greg Turner

    Whether you have the data hard coded in jQuery script, or hard coded in php, it is the same difference – it is bad. The data should come from the database and be changeable via a post or a custom post type or some means such as that.

    You can access data from the database via AJAX – but that is probably over kill for most requirements.

    An easier way to do it is with the action ‘wp_head’. In the function tied to this action, get the data from the database, and output a simple script with a function that returns the data, Then in your jQuery you can call the function in the simple script to retrieve the data,

    This way there is nothing hard coded in either php or jQuery.

    • Pippin

      Greg, there are very, very few scenarios where you should attach an action to “wp_head” for making data available to your Javascript.

      Saying that you should always store data in the database is not really a good way to put it. There is absolutely nothing wrong with have data stored in a variable (not in the database at all), as long as you provide a way to modify / manipulate that data. Most of the time this will be done through add_filter() and apply_filter().

    • Greg Turner

      Pippin – Due to my 30+ years as a programmer and software engineer, working on some extremely complex web applications, I disagree with everything you wrote. So I guess we shall have to agree to disagree. Although I will allow for data to be stored in a variable, but that is not how your post put it.

    • Pippin

      I have no problem with you disagreeing with me πŸ™‚ However, if you disagree with my post here, then you in general disagree with the ways WordPress does things, as the methods described above are used all throughout WordPress, which is also fine to disagree with.

    • Greg Turner

      Yes, I do disagree with bugs that are in WordPress, as well as disagreeing with several design decisions that were made in the creation of WordPress, as well as disagreeing with poor coding styles that are sometimes used. WordPress is far, far from perfect.

    • Pippin

      I would never claim that WP is perfect.

      One thing I would point out further about wp_localize_script() is that one of the best uses for it is for performing Ajax functions on the front end. Using the included admin-ajax.php for processing Ajax functions is by far one of the best ways to do it in WordPress, and in order to do that, you have to make the URL to admin-ajax.php available to your JS file, which is what wp_localize_script is for.

    • Johannes

      Greg, if you’d rather store string translations in the database rather than using gettext, you clearly have not translated much in your 30+ years of programming.

    • Shea Bunge

      You really shouldn’t be dumping scripts or styles in wp_head – the proper way is to register or directly enqueue it using the provided functions. And you could always retrieve the values you pass to wp_localize_script from the database – it’s just that is is not needed in this situation as we are just translating an internal plugin message.Besides, it’s just a tutorial – the focus is on what wp_localize_script does and how to use it – not on where the data comes from.

  7. Paul

    much smarter people than me have been recommending this approach, ( people like Otto who is one of the core developers, and Justin Tadlock ). Here’s a post from 2010 about using wp_localize_script
    http://ottopress.com/2010/passing-parameters-from-php-to-javascripts-in-plugins/

    It is also recommended in the highly acclaimed Professional WordPress development book.
    It also has a performance benefit in that the javascript files being static, they can be cached, whereas dynamically generated scripts cannot

    • Pippin

      Thanks for the support, Paul πŸ™‚

  8. Jack

    Just implementing my js the correct way in the Sermon Manager plugin. This helped – thanks!

  9. Paul

    Great little tutorial pippin, thanks for that, I’ve seen a couple tuts on using wp_localize_script() which went straight over my head, yours just made getting this right, and more importantly properly understanding it, so easy.

    Cheers.

  10. Ron Strilaeff

    @pippin What is in the file js/pw-script.js ?
    Can if be an included js file that I’d plan on using for other things, like a jquery.ajax call and other jquery ui stuff?

    Thanks, Ron

    • Pippin

      I’m not sure I understand the question, sorry.

  11. PeHaa

    Thank you ! You’ve just made my day.

  12. John

    Great Tip. Before I was passing php variables to javascript by doing something like this:
    <?php echo ' var product ='.'"'.$product.'"'.''; ?>

    Thanks!

    • John

      echo ‘ var product =’.'”‘.$product.'”‘.”;

  13. John

    script tags not posting… duh… of course not!

    • Pippin

      If you wrap the code in PRE tags, it will work πŸ™‚

  14. Distjoy

    Waoh, this tut is straight to the point, this is gonna help me alot in my theme developement…thanks!!

  15. Hassan

    Mr. Pippin, just tell me how do I thank you!
    I looked at the Codex page for this function a while back and I couldn’t figure it out. Recently I had to implement this and came across your tut here and in less than 5 min… BOOM! everything works! πŸ˜€

  16. Kaiser

    Or if you want to use a more object oriented JS approach:

    ( function( $, data ) {
    $( ‘#’ + data.buttonID ).on( ‘click’, function() {
    alert( data.alertText );
    } );
    } )( jQuery, pw_script_vars );

    Hopefully the pre tags don’t get deleted in this comment.

    • Luca R.

      I like this approach. It’s much cleaner, has advantages such as optimization when minifying scripts, and it doesn’t throw a warning in JSHint.

  17. Laird Smith

    Thanks Pippin.
    This really helped for a upcoming theme that I am launching soon. All the best.

  18. Bharat Kumar Dhaker

    Can I use wp_localize_script to load script at particular event in my plugin.

    • Pippin

      Can you elaborate?

  19. Bharat Kumar Dhaker

    I want to use wp_localize_script to draw pie chart of google api only on particular action call in my plugin.

    • Pippin

      No, I would not use it for that.

  20. Imperative

    Hey Pippin,

    I’ve been going a bit crazy and Twitter isn’t the best venue to hit up on my question. Here’s the lowdown:

    I was hoping to pass an instance value within a widget class to the JavaScript in order to show/hide *administrative* sections based on true/false checkbox values (e.g. “Show Map”). Front end is easy, admin? Much harder aparently.

    When I drop wp_localize_script() into the widget constructor, it works but I can’t retrieve any instance values. Obviously, if I add the function within function form( $instance ), I get yelled at because the same function is defined in the inactive + all active widget admins.

    Where and how, within the widget class, would I define this in order to pass instance values like a checkbox status to the JavaScript for processing?

    I know it can be done, but for the life of me I can’t figure out how. I’m at my wit’s end here.

    • Pippin

      Are you trying to pass the values to javascript used in the Widget admin or on the frontend of the site when the widget is displayed?

    • Imperative

      Admin. Front end was a breeze, admin not so much.

      I’ve got two conditional sections in a widget that don’t need all their options shown. If I can’t pass the exact widget instance ID, I can’t target the conditional area with a JavaScript.

      For the life of me, I can’t get the scope right. Either the function works but can’t access the instance values or the function errors because it gets called in all instances on the page (inactive + active).

    • Imperative

      I suppose if I had two of the same widget on the front end, I’d run into the same multi-instance issue. Best learn how to solve it now if possible. πŸ™‚

    • Pippin

      Why not just inject the values into the admin_head?

  21. Tim Larsen

    Thanks for this mate – very helpful!

  22. Arshad

    spelling mistake, $(document).read

  23. dinamiko

    Sorry if it’s an outdatet post, but I don’t find a solution to my problem related to wp_localize_script, maybe someone has a solution. The problem is when I try to put more than one in the same page, for now I implemented it this way:

    PHP
    $example_arr = array( ‘example_id’ => ‘123’ );
    wp_localize_script( ‘example_handle’, ‘example_obj’, $example_arr );

    JS
    var id = example_obj.example_id;

    this works well, for example I can use it in a shortcode like this:
    [example id=”123″]

    but if I try to put more than one in the same page:
    [example id=”123″]
    [example id=”456″]

    only the last id is rendered, this is because ‘example_obj’ gets the last value of example_id

    I tried to add an ID to ‘example_obj’ something like this: ‘example_obj’.$id
    but I don’t know how to get it in JS, for example if I created 2 objects:

    ‘example_obj123’ and ‘example_obj456’, how can I get these in my JS?

    thanks in advance πŸ™‚

    • Pippin

      It’s getting overwritten because the “example_obj” has to be unique. It can only be used once.

      Are you calling wp_localize_script() from a short code?

    • dinamiko

      Hi Pippin, thanks for reply,

      finally I don’t use wp_localize_script(), I’m using HTML data-attributes and get these in JS, something like this:

      HTML
      <div class="my_class" data-id="123" …

      JS
      var my_class = document.querySelectorAll(".my_class");

      for( var i = 0; i < my_class.length; i++ ) {
      var id = my_class[i].dataset.id;

      Best

  24. Antonella Perna

    This is not the first time I’ve seen the wp_localize_script function, but certainly is the first time it’s been explained so clearly to me. Thanks so much!

  25. Avenir

    Thanks for your post but in my case, I need to call twice or more times my ShortCode. It’s for display a countdown.
    But with wp_enqueue_script and localize, If I make 2 calls, only the last is running πŸ™
    Example :

    /* <![CDATA[ */
    var plugin_vars = {"rdm":"722656","aa":"2018","mm":"11","jj":"14","hh":"-1","skin":"{dn}{dl} : {hn}h : {mn}m : {sn}s”};
    /* ]]> */

    /* <![CDATA[ */
    var plugin_vars = {"rdm":"814727","aa":"2014","mm":"9","jj":"14","hh":"24","skin":"{dn}{dl} : {hn}h : {mn}m : {sn}s”};
    /* ]]> */

    Any ideas?

    • Pippin

      Why do you need to do it twice?

  26. Webdev20

    You seem very fluent with WordPress API! respect!

  27. Raju

    really great tool. I have ever seen much clear, what i see here. really explained very clearly.. Thank you

Leave a Reply

Error: Please enter a valid email address

Error: Invalid email

Error: Please enter your first name

Error: Please enter your last name

Error: Please enter a username

Error: Please enter a password

Error: Please confirm your password

Error: Password and password confirmation do not match