WordPress developer, consultant, nerd

How to pass data from PHP to JavaScript in WordPress

Back when I first started working with the web, I barely touched JavaScript. At most, I was copy-pasting jQuery snippets to handle simple tasks like email obfuscation or slider initialisation, but I eventually came to realise that I’d have to get my hands dirty. So, I took a leap, learned a whole bunch about JavaScript, and now, many years later, I consider my JavaScript skills to be pretty damn reasonable.

I’m glad I took this leap many years ago, as I’ve since noticed a steady shift towards JavaScript development and nowadays, it is rare for a day to go by where I’m not using the language in some capacity.

One little hurdle every WordPress developer eventually runs into is the problem of how to pass data from PHP into JavaScript? If you’ve done this, you’ll know it’s relatively easy, but I thought I’d share some basic snippets for those who are looking to learn…

Doing it the WordPress way

The typical way to do this in WordPress would be to leverage the wp_localize_script() function. This function basically outputs a <script> tag containing your data in the DOM right before the script itself. This allows the script to use that data by calling on the global variable assigned during the invocation of wp_localize_script().

Here is a quick example of how to use it;

<?php
add_action( 'wp_enqueue_scripts', function () {

   // Register our script
   wp_register_script( 'my-script', get_stylesheet_directory_uri() . '/path/to/theme/scripts/my-script.js', [], false, true );
   
   // Set up the required data
   $myData = [
      'name'            => 'Phil Kurth',
      'country'         => 'Australia',
      'favourite_color' => 'blue',
   ];

   // Localise the data, specifying our registered script and a global variable name to be used in the script tag
   wp_localize_script( 'my-script', 'myData', $myData);

   // Enqueue our script (this can be done before or after localisation)
   wp_enqueue_script( 'my-script' );

} );

If you inspect the DOM, you should now see your data, inside a <script> tag, right before the external script;

There are some caveats to doing it the WordPress way, which you should read about in the codex notes. You should also check out the developer docs on this function for some additional examples.

An alternative approach

I’ve been finding myself using an alternative approach more and more, simply because it offers me more flexibility in how I fragment my templates and mix and match those fragments. The approach I use is similar, in that it drops a script tag into the DOM, but has the advantage of not using a global JavaScript variable. It also allows me to drop the data anywhere in the DOM. Let’s take a look;

<?php
$myData = [
    'name'            => 'Phil Kurth',
    'country'         => 'Australia',
    'favourite_color' => 'blue',
];
?>
<script type="application/json" id="myData"><?= json_encode( $myData, JSON_UNESCAPED_SLASHES ) ?></script>

This will drop the script tag into the DOM – wherever you have decided to put it – and the script tag will now be selectable via its id attribute.

To use this data, we need to pull the text from within this script tag, parse it as JSON, then we’ll have a JavaScript object to use as we need. We could do this, either in the DOM inside another <script> tag, or in another JavaScript file – whatever suits the occasion.

Here is an example of us getting the data from the DOM;

(function ($, window, document, undefined) {

    // run this on document.ready to be sure the script tag is available
    $(function (){

        // if our data block is not available, don't do anything
        var $myData = $('#myData');
        if (!$myData.length)
            return;

        // attempt to parse the content of our data block
        try {
            $myData = JSON.parse($myData.text());
        } catch (err) { // invalid json
            return;
        }

        // if parsing was successful, you should see the data in your console
        console.log($myData);
        
    });

})(jQuery, window, document);

A quick note on the application/json script type

First, you should know that it is not essential to use this type. WordPress doesn’t do it, as you can see by the earlier example image. The reason I’m using it is to prevent the browser from interpreting what is inside that script tag. If you want to test this out, drop this snippet into an HTML file and check your console;

<script>
    console.log('Normal script tag parsed.');
</script>

<script type="application/json">
    console.log('Script tag with type application/json parsed.'); // you shouldn't see this line in your console
</script>

Conclusion

It’s a relatively simple technique, but hopefully this helps someone. If you are having any issues getting this to work, I suggest you get busy with PHP’s var_dump() and JavaScript’s console.log() to dig in and see what is happening at different stages of your code.