Cartoon of Author
via Mastodon


Prevent Tracking Scripts From Running Multiple Times on WooCommerce's Thank You Page


If you've ever installed a custom script on the thank you or order confirmation page of WooCommerce one of the issues you've likely ran into is that the script can be fired multiple times if a user refreshes the page. Personally, I don't see how this happens as often as it does - but - I'll be damned, it seems to be a thing if you don't address it. Perhaps it's those people who never close tabs? 🤔

A lot of plugins that handle integrations for Google Analytics or Facebook Pixels solve for this already, so you likely don't need to worry about it - however - if you're building a custom integration or using some sort of system that doesn't offer a sophistacted integration plugin you'll no doubt run into this problem on a live store.

When I first ran into this problem I was wayyyyy overthinking it, but with a little help from the WooCommerce Slack channel (credit to @pmgarman for clueing me in on the idea!) I found out this is pretty simple to sort with custom meta on the order object.

Here's the snippet that helped me sort this on my end:

// Run Scripts on Order Confirmation Endpoint in WooCommerce Exactly Once.
function zf_woocommerce_thankyou_scripts($order_id) {
	// Check for meta key on order, only run if not found.
	if( ! get_post_meta( $order_id , '_tracking_scripts_ran', true ) ) {
		// Add meta key to order so scripts don't run a second time.
		add_post_meta( $order_id, '_tracking_scripts_ran', 'yes', true );  ?>
		<script type="text/javascript">
			<!-- Your Tracking Script(s) here --> 
	<?php }
add_action( 'woocommerce_thankyou', 'zf_woocommerce_thankyou_scripts' );

All you should need to do is replace the <script></script> above with whatever tracking scripts you need to integrate.

The way this snippet works is simple, it checks for a custom meta key _tracking_scripts_ran on the order when the thank you page loads, if it doesn't exist it'll add it and display the scripts.

The second time around (ie after a refresh, etc.) it'll see that the meta exists and won't render the script to run again.

That outta do it, much easier than I was originally thinking it would be.

As always you can install that snippet in your functions.php - or - use something like the Code Snippets plugin.

PS: If you're trying to pull in some data from the $order object for a custom event I'd recommend taking a peek at the cheat sheet over at, those are always super helpful for me!