When a JavaScript file enqueued with wp_enqueue_script() needs access to server-side data — an AJAX endpoint URL, a nonce, translated strings, or dynamic configuration — the usual approach is wp_localize_script(). It serialises a PHP array to JSON and outputs it as a <script> block immediately before the enqueued script tag, creating a global JavaScript variable of the form var objectName = {...};. WordPress 4.5 added wp_add_inline_script(), which appends (or prepends) arbitrary JavaScript to any enqueued script handle. The difference matters: wp_localize_script() can only produce a JSON object assignment, while wp_add_inline_script() can output any JavaScript — function calls, library initialisers, conditional logic, const/let declarations, or module-style code. In practice, use wp_localize_script() for passing data objects to your own scripts, and wp_add_inline_script() when you need to call a third-party library initialisation function with server-generated parameters.
Problem: You're embedding a Google Maps instance that requires calling initMap() with a server-generated API key and coordinates. wp_localize_script() can only produce a JSON object — you need to call a function after the Maps library loads.
Solution: Use wp_add_inline_script() to append the initialiser call after the library script handle. Use wp_localize_script() for your own scripts where a JSON data object is sufficient.
<?php
add_action( 'wp_enqueue_scripts', 'enqueue_map_script' );
function enqueue_map_script() {
// 1. wp_localize_script — output: var mapConfig = {...};
wp_enqueue_script( 'my-map', get_template_directory_uri() . '/js/map.js', [], null, true );
wp_localize_script( 'my-map', 'mapConfig', [
'apiKey' => get_option( 'my_maps_api_key' ),
'lat' => get_post_meta( get_the_ID(), 'location_lat', true ),
'lng' => get_post_meta( get_the_ID(), 'location_lng', true ),
'zoom' => 14,
] );
// 2. wp_add_inline_script — output: arbitrary JS after the script tag
// Use 'after' (default) to append after the script, or 'before' to prepend
$api_key = esc_js( get_option( 'my_maps_api_key' ) );
wp_enqueue_script(
'google-maps',
"https://maps.googleapis.com/maps/api/js?key={$api_key}&callback=initMap",
[ 'my-map' ],
null,
true
);
// Inline script that runs AFTER google-maps loads:
wp_add_inline_script( 'google-maps',
'window.initMap = function() {
var map = new google.maps.Map( document.getElementById("map"), {
center: { lat: parseFloat(mapConfig.lat), lng: parseFloat(mapConfig.lng) },
zoom: parseInt(mapConfig.zoom, 10)
});
};',
'before' // 'before' = output BEFORE the google-maps script tag
);
}
Comparison summary — when to use which:
<?php
// wp_localize_script — best for:
// ✓ Passing a data object to your own JS file
// ✓ Nonces, AJAX URLs, translated strings
// ✗ Cannot output function calls or non-JSON values
wp_localize_script( 'my-script', 'myData', [
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'my_action' ),
'strings' => [ 'error' => __( 'An error occurred.', 'textdomain' ) ],
] );
// wp_add_inline_script — best for:
// ✓ Third-party library initialisers
// ✓ Conditional logic around a script
// ✓ const/let declarations (wp_localize_script uses var)
// ✓ Module initialisation patterns
wp_add_inline_script( 'my-script',
'const APP_VERSION = ' . wp_json_encode( THEME_VERSION ) . ';'
);
NOTE: wp_localize_script() uses var and creates a global variable. For modern ES6+ code where you want const scoping or module patterns, wp_add_inline_script() gives you full control over the output. Also, both functions must be called after wp_enqueue_script() for the same handle — calling them on a script that hasn't been enqueued has no effect.