WordPress includes a lot of helper functions that can make your life as a developer much easier. One function in particular that I really love is add_query_arg(), which provides an extremely simply way to append query variables to any URL. Query vars, in case you’re not familiar with them, allow you to perform any number of tasks based on the information passed through the URL.

The add_query_arg() function accepts three parameters:

  • name – the argument name
  • value – the value of the argument in the first parameter
  • URL – the URL to append the argument to. This defaults to the current URL

Let’s say, for example, that you want to create a button that redirects to a URL like this:

http://yoursite.com/?view=list

The view variable can be used, for example, to modify your template layout, and so you might also have this:

http://yoursite.com/?view=grid

It is pretty easy to create your URL like this:

<?php echo home_url('?view=list'); ?>

But if you are dealing with more complex URL structures, especialy URLs that are not always the same, perhaps because they contain other query variables, this does not work reliably. And this is where add_query_arg() comes in.

The example below will render the exact same thing as the example above with home_url(), but it will be much more flexible (I’ll show you why in a moment):

<?php echo add_query_arg( 'view', 'list', home_url() ); ?>

The result of this will be:

http://yoursite.com/?view=list

The question you should ask now is “why should I use add_query_arg() instead of just adding ?view=list to my URL?”. The answer is simple: add_query_arg() allows you to append a query arg to any existing URL without disturbing existing variables AND it will ensure that the resulting URL has proper trailing slashes (or doesn’t). Take the following URL as an example:

http://yoursite.com/?something=value&second-var=this-value

Imagine that is the URL you are working with and you need to now append the “view=list” argument. First of all, the following will fail:

http://yoursite.com/?something=value&second-var=this-value?view=list

It will fail because only the very first argument starts with a ?, all others are separated with an &, so this puts you in a situation where you need to do some checking to figure out whether you need to use “?view=list” or “&view=list”. Checks like that, while not terribly difficult, do require a couple of conditional checks. Why do that when you can simply do the following?

1
2
3
4
5
6
7
<?php 
echo add_query_arg(
	'view',
	'list',
	'http://yoursite.com/?something=value&second-var=this-value'
);
?>

The add_query_arg() function will take care of adding our new argument with either ? or &. This means that the following will also work:

1
2
3
4
5
6
7
<?php 
echo add_query_arg(
	'view',
	'list',
	home_url()
);
?>

And let’s say that you don’t necessarily know what the URL is, or perhaps you just want to append the arguments to the current URL, no matter what it is. You can do this:

1
2
3
4
5
6
<?php 
echo add_query_arg(
	'view',
	'list'
);
?>

By leaving out the third parameter, WordPress will simply append your arguments to whatever the current URL is, including any existing query variables.

Adding Multi Query Arguments

Often times you will need to add multiple variables to your URL, and add_query_arg() makes this extremely simple. The first two parameters can be replaced with an associative array of key to value pairs. Like this:

1
2
3
4
5
6
7
8
9
<?php
echo add_query_arg(
	array(
		'var_key' => 'key_value',
		'another_var' => 'My Value'
	),
	home_url()
);
?>

This will result in a URL like this:

http://yoursite.com/?var_key=key_value&another_var=My%20Value

Note that add_query_arg() takes care of URL encoding the values through the use of urlencode_deep() automatically, so there is no need to encode the values yourself.

Second note: add_query_arg() does not escape the values returned so please be sure you properly escape URLs from this function. For example:

echo esc_url( add_query_arg( array( 'action' => 'edit', => 'post_id' => $_REQUEST['id'] ) ) );
  1. Gijs

    Hi Pippin,

    Very, very useful. Needed this before and built it myself, because I didn’t know this helper existed.
    Thanks!

    Gijs

  2. Syamil MJ

    For added security, especially for dynamically generated URLs, use esc_url e.g.

    echo esc_url(add_query_arg(
    	array(
    		'var_key' => $some_var,
    		'another_var' => $some_var2
    	),
    	home_url()
    ));
    
  3. Cathy Finn-Derecki

    When is this called? What hook do I use to render this link in a list of posts, say, in a “recent posts” widget? I want to add a query argument to all posts with a variable.

    • Pippin

      Yep, sure enoughm you are right.

  4. Deb

    instead of home_url, if we want to use it on product category URLs only, then how shall we use it?

  5. Deb

    I want to add URL parameter on product categories dynamically, for example:

    by default you have product category url like:
    example.com/product-category/furniture/living/armchairs/

    Now I want to append:
    example.com/product-category/furniture/living/armchairs/?fwp_product_categories=armchairs (append the last category dynamically).

Comments are closed.