73

Don't use admin-ajax

AJAX in WordPress can be hard to understand.

AJAX in WordPress

Websites used to reload pages for everything and anything. Every time a form was submitted, the page was reloaded.

Now we have great tools to make awesome experiences and page reload is not something we gonna regret.

AJAX is a technique that involves several languages such as PHP and javaScript. It works asynchronously behind the scene.

In WordPress, all AJAX calls are processed by the same unique admin file: /wp-admin/admin-ajax.php.

What’s the problem?

WordPress provides functions that developers can use to set up advanced AJAX processing. This is cool only for that purpose: the easiness.

Unfortunately, this gives shitty performances :

  • you have to call a file located in the admin area to perform actions on the frontend!
  • every single AJAX request loads an entire WordPress with all files and codes (which is huge)
/** Load WordPress Bootstrap */
require_once( dirname( dirname( __FILE__ ) ) . '/wp-load.php' );

Security issues?

Be careful with that. A lot of developers skip the use of nonces which makes their AJAX calls less safe.

Source

Besides, there are multiple things to check such as permissions and capabilities.

Shitty performances

This point is undeniable.

Even wp job manager by Automattic does not use admin-ajax!

$ajax_url = WP_Job_Manager_Ajax::get_endpoint();

Alternatives

There are other approaches.

Duplicate admin-ajax.php and remove useless parts

The worse idea to me. It will be less heavy but at the end of the day, you are still loading the entire WordPress for every fucking single AJAX request.

Besides, there might be security issues with this « solution ». Please, do not do this.

Source

Custom AJAX URL

The classic WP AJAX way might look like that :

<?php
wp_enqueue_script( 'handle_script_custom',  '/url/to/js/script-ajax.js', ['jquery'], 'version', true );		
wp_localize_script( 'handle_script_custom', 'name_js_object_for_ajax', [ 'ajax_url' => admin_url( 'admin-ajax.php' ), 'ajax_nonce' => wp_create_nonce( 'do_some_ajax' ) ] );

It allows for the following usage :

jQuery.post(
    name_js_object_for_ajax.ajax_url,
    {
        'action': 'mon_action_ajax',
        'nonce': name_js_object_for_ajax.ajax_nonce
    },
    function(response){
        console.log(response);
    }
);

But don’t call admin-ajax, make your own AJAX URL :

$ajax_url = WP_Job_Manager_Ajax::get_endpoint();
wp_localize_script( 'handle_script_custom', 'name_js_object_for_ajax', [ 'ajax_url' => $ajaxurl ] );

It’s a little bit more complicated but it significantly improves performances. Even Automattic does not use wp-ajax.

Use WP REST API

A nice and clean approach!

How to

Please read the following articles, they are great : 

This way, you don’t have to call admin-ajax file anymore, instead, you just grab some JSON data which is pretty faster :

$.ajax( {
    url: '/wp-json/posts?filter[posts_per_page]=7',

Be cautious

WP REST API might be tricky though :

  1. Before using REST API, make sure your custom post types and taxonomies support the « show_in_rest » parameter (MUST be set to true)
  2. Check the disable REST API admin page if you use it, your endpoint MUST be whitelisted
  3. Make sure you are using nonces to secure your calls source

Great side effects?

With the WP REST API, you can create your own endpoints. This is better for maintenance.

Wrap up

WP Ajax is still a good thing but only in the admin area. Please use alternative approaches for any frontend request.

The final result will be cool and you will probably prevent a lot of unwanted side effects.

The REST API approach is the best method I’ve found so far.