Most WordPress AJAX bugs aren't complex. They're one missing line.
The problem
function handle_ajax_raw() {
echo 'Done';
}
add_action( 'wp_ajax_custom_action', 'handle_ajax_raw' );This looks fine. But WordPress doesn't stop after your function runs. It may append extra output, debug info, or theme markup to the response. Your frontend receives a dirty string instead of clean data.
The fix
function handle_ajax_proper() {
echo 'Done';
wp_die();
}
add_action( 'wp_ajax_custom_action', 'handle_ajax_proper' );wp_die() terminates execution immediately after your response. Nothing else gets appended.
Better: use wp_send_json_success()
function handle_ajax_json() {
wp_send_json_success( array( 'message' => 'Done' ) );
}
add_action( 'wp_ajax_custom_action', 'handle_ajax_json' );wp_send_json_success() sets the correct `Content-Type: application/json` header, encodes your data, and calls wp_die() internally. One function. No loose ends.
Use wp_send_json_error() for failures. Your frontend can check response.data.success consistently across all handlers.
AJAX responses should be clean and predictable. One missing line breaks everything silently.
