Scroll to top

With 3.6, aka "Oscar", just released, lets take a look at some of the new features that are available to developers. In particular, in this series I'll be looking at the new heartbeat API, and demonstrating how you can make use of it in your plugins and themes.


What Is the Heartbeat API?

The heartbeat API allows for regular communication between the user's browser and the server. One of the original motivations was to allow for locking posts and warning users when more than one user is attempting to edit a post, or warning the user when their log-in has expired.

This 'communication' involves routinely sending data to the server, which then responds with any appropriate data. The API allows for plugins to attach their own data at both ends, giving your plugin the ability to also communicate between server and browser. You can think of these stages (data sent from browser to server, and response sent from server to browser) as the two 'beats' that constitute a cardiac cycle. This whole process is repeated at regular intervals. This all happens in the background, so most of the time you'll probably never know it's there.


Sending Data From Browser to Server

By default Heartbeat starts running automatically, but it only ever sends data to the server when it has data to send. To enqueue data you must use the wp.heartbeat.enqueue() function in your JavaScript file. This function takes three arguments:

  • Handle – (string) This is just a string identifier for your data. Make sure it's unique.
  • Data – (object) The data to send as an object.
  • Override – (bool) Whether to over-ride existing data. If true, any data previously added with the provided handle is replaced. If false and data already exists for that handle it does nothing.

For example:

1
2
wp.heartbeat.enqueue(
3
	'wptuts-plugin',
4
	{
5
		'foo': 'bar',
6
		'wp': 'tuts',
7
	},
8
	false
9
);

Note: Any data that is sent with a beat is immediately removed from the queue. Data enqueued after that point is sent with the next beat.

To check if a particular handle already has data waiting in the queue, or to retrieve that data, you can use the wp.heartbeat.isQueued(). This function takes a handle as its only argument and returns either null or the associated data waiting in the queue.

This is useful, for example, if you want to append extra arguments to already queued data:

1
2
	// Data to add

3
	var new_data = {
4
		'version': '3.6'
5
	};
6
7
	if ( data = wp.heartbeat.isQueued( 'wptuts-plugin' ) ) {
8
		// Data already exists - merge data with new data

9
		new_data = jQuery.extend( data, new_data );
10
	}
11
12
	// Queue and over-ride existing data

13
	wp.heartbeat.enqueue(
14
		'wptuts-plugin',
15
		new_data,
16
		true
17
	);
18
19
	/*

20
	wptuts-plugin now has the data and new_data associated with it:

21
	{

22
		'foo': 'bar',

23
		'wp': 'tuts',

24
		'version': '3.6'

25
	};

26
	*/

Tip: You should list 'heartbeat' as a dependency for any JavaScript files which make use of this API. We'll be covering this, along with a working example plugin, in part three.


Sending Data From Server to Browser

At the next 'beat' the above data is sent to the server, when this data is received server-side there are three hooks which are triggered:

  • heartbeat_received – This filters the server's response to the browser. It also passes the data received from the browser and the admin screen ID (or 'front' if this request is from the front-end).
  • heartbeat_send – This hook also filters the server's response to the browser. Its only difference to the above filter is that it does not pass the received data.
  • heartbeat_tick – This action is triggered just before the response is set. It passes the response array and screen ID as arguments.

If the current user is logged out then the hooks:

  • heartbeat_nopriv_received
  • heartbeat_nopriv_send
  • heartbeat_nopriv_tick

are triggered instead. (nopriv stands for no privileges)

For the most part you'll probably only need the first of these filters: heartbeat_received / heartbeat_nopriv_received. These filters pass the data received from the browser and so allow us to check if we have any data associated with our handle, before including our response:

1
2
function wptuts_respond_to_browser( $response, $data, $screen_id ) {
3
	if ( isset( $data['wptuts-plugin'] ) ) {
4
		// We have data with our handle! Lets respond with something...

5
6
		// echo $data['wptuts-plugin']['foo']; //prints 'bar';

7
		$response['wptuts-plugin'] = array(
8
			'hello' => 'world'
9
		);
10
	}
11
	return $response;
12
}
13
14
// Logged in users:

15
add_filter( 'heartbeat_received', 'wptuts_respond_to_browser', 10, 3 );
16
17
// Logged out users

18
add_filter( 'heartbeat_nopriv_received', 'wptuts_respond_to_browser', 10, 3 );

Listening for the Return 'Beat'

Finally, to complete the cycle, we can listen for when the response from the server is received by the browser. When this happens WordPress triggers the event heartbeat-tick. We can hook onto this with our callback to process the response:

1
2
jQuery(document).ready( function($) {
3
4
	$(document).on( 'heartbeat-tick.wptuts-plugin', function( event, data ) {
5
		if ( data.hasOwnProperty( 'wptuts-plugin' ) ) {
6
			console.log( data['wptuts-plugin'] );
7
			// Prints to the console { 'hello' : 'world' }

8
		}
9
	});
10
11
});

Note: It is strongly recommended that you use namespaced events, that is you bind your callback to heartbeat-tick.{unique namespace} as above, and not to just heartbeat-tick.

That, in essence, is how to take advantage of the Heartbeat API. In the next part of the series we'll be looking at ways you can manipulate the pulse of the beat. In the final part we'll create a working example of a plugin which uses the API.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.