I have several Javascript files e.g. TITLE.js with this format and they all work fine:
jQuery( document ).on( 'click', '.click-TITLE-link', function(event) {
event.preventDefault();
var post_id = jQuery(this).data('id');
jQuery.ajax({
url : TITLElink.ajax_url,
type : 'post',
data : {
action : 'click_TITLE_process',
nonce : TITLElink.ajax_nonce,
post_id : post_id
},
success : function( response ) {
if (response) {
// DO SOMETHING
}
}
});
})
Each javascript file is associated with a code snippets that look like this:
<?php
add_action( 'wp_enqueue_scripts', 'ajax_TITLE_link_enqueue_scripts' );
function ajax_TITLE_link_enqueue_scripts() {
wp_enqueue_script( 'TITLE-link', get_theme_file_uri( '/js/TITLE.js' ), array('jquery'), '1.0', true );
wp_localize_script( 'TITLE-link', 'TITLElink', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'ajax_nonce' => wp_create_nonce( 'link_TITLE_accept_' . admin_url( 'admin-ajax.php' ) ),
));
}
// action to execute AJAX call
add_action( 'wp_ajax_nopriv_click_TITLE_process', 'click_TITLE_process' );
add_action( 'wp_ajax_click_TITLE_process', 'click_TITLE_process' );
function click_TITLE_process() {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && wp_verify_nonce( $_POST['nonce'], 'link_click_TITLE_' . admin_url( 'admin-ajax.php' ) ) ) {
// Do something here
// redirect back to the page
echo "Refreshing";
} else {
die( 'Security check failed' );
}
}
It seems cumbersome and not good practice to have a separate javascript file for each function, but before I give consolidation a go, I'm worried that the NONCE part won't work?
Any help much appreciated. TIA.
One clean way to merge all those almost‑identical snippets into one JavaScript file and one PHP enqueue/nonce block, while keeping every AJAX action separate and secure.
/**
* Front‑end AJAX helpers.
*/
function mytheme_enqueue_ajax() {
// 1. Enqueue just **one** JS file.
wp_enqueue_script(
'mytheme-ajax',
get_theme_file_uri( '/js/mytheme-ajax.js' ),
array( 'jquery' ),
'1.0',
true
);
// 2. Localise the URL and a single nonce.
wp_localize_script(
'mytheme-ajax',
'myAjax',
array(
'url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'mytheme_ajax' ),
)
);
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_ajax' );
Why a single nonce is fine
A WordPress nonce just confirms the request came from your site (protects against CSRF).
It does not need to be unique per action. One fresh nonce, verified server‑side, is enough.
Keep your handlers, but use the same nonce key when you verify:
add_action( 'wp_ajax_click_title_process', 'click_title_process' );
add_action( 'wp_ajax_nopriv_click_title_process', 'click_title_process' );
function click_title_process() {
check_ajax_referer( 'mytheme_ajax', 'nonce' ); // <‑‑ exact same key used in wp_create_nonce
$post_id = absint( $_POST['post_id'] );
// …do your work here…
wp_send_json_success( 'Done' ); // ends nicely
}
Duplicate that add_action
/ callback pair (or use a switch) for any other action names you need.
All of them can share the same check_ajax_referer( 'mytheme_ajax', 'nonce' )
.
/js/mytheme-ajax.js
jQuery(function ($) {
// Delegate to *any* element that carries data-ajax-action
$(document).on('click', '[data-ajax-action]', function (e) {
e.preventDefault();
const $el = $(this);
const action = $el.data('ajax-action'); // e.g. click_title_process
const id = $el.data('id'); // whatever post ID you stored
$.ajax({
url: myAjax.url,
type: 'post',
data: {
action: action,
post_id: id,
nonce: myAjax.nonce
},
success(response) {
// Do something with response if needed
console.log(response);
},
error(xhr) {
console.error(xhr.responseText || 'Ajax failed');
}
});
});
});
<a href="#" class="click-link"
data-ajax-action="click_title_process"
data-id="123">Do Something</a>
Give each button/link the appropriate data-ajax-action
and data-id
.
The same JavaScript picks them all up and calls the correct PHP action.