Without a doubt, Gatsby's most powerful feature is being able to pull data from multiple sources and serve that data statically on build time. This creates a blazing fast experience for websites with CMS's behind the scenes, but also creates a complication if you regularly update your website with new content, because you'd need to manually re-build and re-deploy your website so the updated content kicks in.
Thankfully the new technologies available for serverless websites allow us to create easy workarounds for this problem. For example if you have a Gatsby website that serves data from WordPress and it's hosted on ZEIT's Now, we can add a "Deploy Now" button to your WP Admin panel. Here's how:
Creating a Deploy Hook
First we'll need to create a Deploy Hook in our project's settings. Deploy Hooks are unique URL's that allow you to trigger a deployment of a given branch. This is extremely helpful for our purpose, right?
To create a Deploy Hook, go to your project's settings inside ZEIT's dashboard, then inside "GIT Integration" create a new Deploy Hook for your production
branch (probably master
).
Once you created your Deploy Hook, all it takes to deploy your branch is to make a POST request to the given URL like this:
$ curl -X POST "your_deploy_hook_url"
Once you made the POST request, the selected branch should start deploying and you should get a response like this:
{
"job": {
"id": "A7OcAEEgNRh61p1VZXE1",
"state": "PENDING",
"createdAt": 1564399503217
}
}
We're half way there! Now we just need to add a button to the WP Admin panel that makes a POST request to the Deploy Hook.
Add a "Deploy Now" button to the WP Admin
Now we need to add an identifiable button to the WP Admin bar. We can do this by using Wordpress' admin_bar_menu
hook. So, in your functions.php
file in your theme directory add the following:
<?php
// Add a 'Deploy Now' button to WP Admin bar
function add_deploy_button($wp_admin_bar) {
$args = array(
'id' => 'deployButton', // ID of the button added.
'title' => 'Deploy Now',
'href' => '#'
);
$wp_admin_bar->add_node($args);
}
// WP Hook
add_action('admin_bar_menu', 'add_deploy_button', 100);
?>
Excellent! Now we need to create a JavaScript file inside our theme directory, to do a POST request to our Deploy Hook every time we click the "Deploy Now" button.
const deployButton = document.querySelector('#wp-admin-bar-deploy-button > a')
if (deployButton) {
deployButton.addEventListener('click', (event) => {
event.preventDefault()
// To make the POST Request will use
// the gud-ol jQuery that comes with WordPress
jQuery.ajax({
url:
'', // Our Deploy Hook URL here,
method: 'POST',
}).done(() => {
alert(
'Your website will be updated shortly. Check in a couple of minutes'
)
})
})
}
Great we're almost there! Now we just need to include this script in the Admin page. We'll do this by using the admin_enqueue_script
WP Hook. Again, inside your functions.php
file, add the following:
<?php
function add_deploy_script() {
wp_enqueue_script('deploy_script', get_template_directory_uri() . '/path/to/your/script.js');
}
add_action('admin_enqueue_scripts', 'add_deploy_script');
?>
Yayyy! We did it! āØ Now every time you finish adding some content through the WP Admin, all you have to do to deploy your website is click the "Deploy Now" button.
Hoped this little workaround helped you ā
Stay safe. Stay home!
Top comments (3)
Hi Tom, this is exactly what I've been looking for, thanks !
However I've had one issue. I can't get my JS to recognise the element on the page using querySelector.
I noticed in your code you labelled the button deployButton and gave the full ID of the element as '#wp-admin-bar-deploy-button > a'. Was this deliberate? I would have expected it to be #wp-admin-bar-deployButton > a.
Either way, I can't get the script to recognise the element to add the event listener - is this code working for you still ?
I posted my code below, though it's pretty much a straight copy of yours with a couple of extra elements added in at the top to see what was firing, and deploy-button changed to deployButton.
Thanks for any advice you have! Tom
const deployButton = document.querySelector('#wp-admin-bar-deployButton > a')
console.log('JS loaded!') // fires on page load
if (deployButton) {
console.log(
'There is a deploy button!' // Never fires, and so nor does anything below this line...
)
In case anyone else has this issue, I solved it by wrapping the JS code in :
window.onload = function() { ... above code }
This prevents the JS trying to find the element to apply the listener to before the page is fully rendered.
Hey Tom! Sorry for the late answer!
Iām happy you solved this one :)
Next time, feel free to DM me on Twitter or send me an email.
Cheers!