WordPress wp_add_inline_script vs wp_localize_script: When to Use Each

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.