Dorokhov.codes

14. AJAX

URL

All WordPress AJAX requests must be sent to wp-admin/admin-ajax.php.

If the page is from the administration area, WordPress sets the correct URL in the global JavaScript variable ajaxurl.

For a page from the public area, you will need to establish the correct URL yourself and pass it to jQuery using wp_localize_script().

wp_enqueue_script(
    'tfi-address-processor',
    plugin_dir_url( __FILE__ ) . 'js/tfi-address-processor.js',
    array( 'jquery' )
);

wp_localize_script(
    'tfi-address-processor',
    'app',
    [ 'ajaxurl' => admin_url( 'admin-ajax.php' ) ]
);

Hooks for AJAX requests

We should use the next name for the hook: wp_ajax_MY_FUNCTION and wp_ajax_nopriv_MY_FUNCTION.

add_action('wp_ajax_get_chairs', [ self::class, 'get_chairs_ajax' ] );
add_action('wp_ajax_nopriv_get_chairs', [ self::class, 'get_chairs_ajax' ] );

Example:

public static function get_chairs_ajax() {

    $chairs = Chair_Picker_Tool_Table::get_all();
    
    header( 'Content-Type: application/json' );

    echo json_encode( [ 'data' => $chairs ] );

    die();
}

Test:

/wp-admin/admin-ajax.php?action=get_chairs

Frontend example

const ajax = $.ajax({
    url: app.ajaxurl,
    method: "POST",
    data: {
        action: 'get_company_info',
        vat : '1234567'
    }
});

ajax.done((response) => {
    alert("done " + response);
});

JSON

function get_comparison_table() {

    // Ensure this is an AJAX request
    if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
        wp_die();
    }

    // Sample data (replace with actual data fetching logic)
    $data = [
        1 => [ 'title' => 'Title 1', 'link' => 'https://link1' ],
        2 => [ 'title' => 'Title 2', 'link' => 'https://link2' ],
        3 => [ 'title' => 'Title 3', 'link' => 'https://link3' ],
    ];

    // Return JSON response
    wp_send_json_success( $data );
}

wp_send_json_success() function:

  1. Checks if it’s an AJAX request – Ensures the function is accessed only via AJAX.
  2. Defines sample data – Replace this with real database queries if needed.
  3. Uses wp_send_json_success – Sends a JSON response that includes success: true and the data.

I used wp_send_json_success() instead of exit() because wp_send_json_success():

  1. Automatically sets the correct headers – It sets Content-Type: application/json and ensures proper encoding.
  2. Echoes the JSON response – No need to use json_encode() manually.
  3. Calls wp_die() internally – This safely terminates execution, making exit() unnecessary.

Nonce

For requests that could result in a change to the database you need to send a nonce so the server knows the request came from a legitimate source.