Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am developing an admin-only plugin, which uses some ajax calls in its interface. The website itself also relies on ajax calls on its front-end, too.

I'd like to be able to identify when the WP is loaded due to "simple backend call", "AJAX backend call" or "AJAX frontend call". The use case, in its simplest form, could be to load my plugin only on admin pages or ajax calls from them. Besides, it helps not to break the front-end while developing on a live site :)

So far, I found the following:

  • is_admin() returns true on all AJAX calls (which is strange, imho)
  • as all my AJAX calls are done via jQuery, I can determine an AJAX call by HTTP variable HTTP_X_REQUESTED_WITH (see here).

But I still cannot figure out how to distinguish between admin-side AJAX and front-side AJAX. Any ideas?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

I understand the problem you are having, I was thinking of the same thing.

It is not really a problem tho, it's more a matter of good programming design and have a good separation of front-end and back-end.

Now the way I have managed to solve this is doing the following:

I hope you are calling your AJAX action with wp_localize_script. We are going to extend this is a little by implementing it this way:

        'my_ajax_url' => admin_url( 'admin-ajax.php' ),
        'my_frontend_call' => 'something-here',
        'my_nonce' => wp_create_nonce( 'my_nonce' )

This is ONLY added in the frontpage, I am sure you know how this works. Now as you know this will add a little piece of javascript. Note here the variable my_frontend_call, this is the important one we are going to use.

More instructions on how to set up a good ajax call here: link

Now we have this all set up, now we can easily implement the logic in the backend as this:

// Here we check that we are facing the backend.
// This will also be true if we are facing the 
// frontend but making an AJAX call. 
// As you say bad, also IMO
if( is_admin() )
        //Now here we are going to put the magic
            // Now these actions are loaded only when `my_frontend_call` is set
            // You can add everything here that only get's loaded on a call where
            // `my_frontend_call` is set
            add_action('wp_ajax_handle_frontend_ajax', 'handle_frontend_ajax_callback');
            add_action('wp_ajax_admin_only_ajax', 'admin_only_ajax_callback');

Now you can mix this up a little with different variables from different locations.

I don't know why this isn't a known recommendation. In my opinion it's ugly when stuff get's loaded when it is not even needed.

NOTE I still am new to WordPress, so maybe this is not a good method, I hope some of the professionals here can comment on this.

share|improve this answer
Nice, I like the approach! –  Aurimas Dec 9 '11 at 13:50

is_admin() returns true on all AJAX calls (which is strange, imho)

This is not strange, because Ajax calls follow much more of admin load logic, than front-end. Essentially Ajax load is specialized version of admin load.

The use case, in its simplest form, could be to load my plugin only on admin pages or ajax calls from them.

Not sure what you mean here. Script queueing does not depend on Ajax. If you don't want script on front end - don't load it there.

Modern WordPress does not rely on referrers and such for detection where call came from, instead nonces should be used for source and intent verification.

Since it is your own code than simplest way to distinguish request is to have request carry explicit argument with information is it from front or back.

share|improve this answer
Let me try to explain once more. I do not want my plugin to load on front-end (because it does not have anything to do with it, and would only do unnessasary initialisation). For simple page views, I can simply check with is_admin(). But I cannot do it for AJAX calls coming from front-end, because is_admin() returns true, too. And that is what I am trying to figure out. P.S. I disagree that AJAX load is a specialised version of admin load. It's not, if it's initiated by a simple user visiting the site. The user does not have anything to do with administration. –  Aurimas Oct 10 '11 at 7:16
@Aurimas If you don't load your plugin on front end then you won't get requests from front end. There would be no code to send them. I disagree that AJAX load is a specialised version of admin load. This is not conjecture, this is just stating facts of technical implementation. Ajax requests are handled by file in admin area and trigger hooks of admin area during load. –  Rarst Oct 10 '11 at 9:10
I understand, but it would still be loaded on front-end AJAX calls (which are handled by a completely separate plugin), and I'd like to avoid that. –  Aurimas Oct 10 '11 at 10:35
@Aurimas I am sorry, but I don't follow your setup at all. Maybe you could add some details to question? –  Rarst Oct 10 '11 at 11:29
is_admin() returns always true whether it is from back or front ajax request.

My idea is very simple. Just define two different names for the nonce field. (So, other than the developer, no one will know which name for which purpose.) Example:

add_action('wp_ajax_{my_ajax_hook}', 'my_ajax_function');
function my_ajax_function() {

    if( isset($_REQUEST['f_nonce']) ){
        $fromFront = true;
        $nonceField = 'f_nonce';
        //by default from backend or you can alter;
        $fromFront = false;
        $nonceField = 'b_nonce';

    if ( ! wp_verify_nonce( $_REQUEST[$nonceField], 'my-nonce-pass' ) ) {
        die( 'Security check' ); 

    } else {
        // Do stuff here according to the value of $fromFront;


The nonce data should be with each ajax call to secure your script according to http://codex.wordpress.org/AJAX_in_Plugins .

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.