Skip to content

AJAX

AJAX lets pages communicate with the server in the background without a full reload. Lumbermill provides a typed action system for registering and calling AJAX endpoints.

AJAX is disabled by default. Run the activate command to enable it and scaffold an example action:

Terminal window
wp instance activate ajax

This sets enabled => true in config/ajax.php and creates app/Ajax/Action/ExampleAjaxAction.php.

To add an AJAX endpoint you need to:

  • Create an AJAX action class
  • Register the action in config
  • Add a nonce attribute to your markup
  • Call the action from JavaScript

Use the generate command to scaffold a new action class:

Terminal window
wp instance make ajax GetPosts
# → app/Ajax/Action/GetPostsAjaxAction.php

Or create it manually in app/Ajax/Action/. Every action class must extend BaseAjaxAction:

<?php
namespace App\Ajax\Action;
use App\Lib\Ajax\BaseAjaxAction;
class GetPostsAjaxAction extends BaseAjaxAction
{
protected function callback(): void
{
// Your code here
}
}

Use success() or error() to return JSON to the client:

protected function callback(): void
{
$this->success([
'message' => 'Hello world!'
]);
}

Add the action to config/ajax.php:

use App\Ajax\Action\GetPostsAjaxAction;
return [
'enabled' => true,
'actions' => [
'getPosts' => [
'class' => new GetPostsAjaxAction,
],
],
];

Add a nonce attribute to the element that triggers the action:

<button
data-nonce="{{ nonce_ajax('ajax.actions.getPosts') }}"
class="ajax-button"
>
Get posts
</button>

Note: The argument passed to nonce_ajax is the action key from the config.

import { createClient } from '@/lib/AjaxClient';
const button = document.querySelector('.ajax-button');
const nonce = button.dataset.nonce;
const getPostsClient = createClient('getPosts', nonce);
button.addEventListener('click', async () => {
const response = await getPostsClient.post();
const data = await response.json();
console.log(data);
});

Pass an object to post() to send data:

getPostsClient.post({
foo: 'bar',
});

Access it server-side with the typed request helpers:

protected function callback(): void
{
$foo = $this->requestVarString('foo'); // 'bar'
}

Available helpers: requestVarString, requestVarInt, requestVarFloat, requestVarBool.

A nonce is like a secret code that changes every time you want to send a message. It adds an extra layer of security by ensuring that even if someone figures out the code once, it won’t work again because it’s always different.

WordPress Nonces