add_rewrite_tag( string $tag, string $regex, string $query =  )

Adds a new rewrite tag (like %postname%).


The $query parameter is optional. If it is omitted you must ensure that you call this on, or before, the ‘init’ hook. This is because $query defaults to $tag=, and for this to work a new query var has to be added.


Name of the new rewrite tag.
Regular expression to substitute the tag for in rewrite rules.
String to append to the rewritten query. Must end in '='.


More Information

This function can be used to make WordPress aware of custom querystring variables. Generally, it’s used in combination with add_rewrite_rule() to create rewrite rules for pages with custom templates.

If you use this function to declare a rewrite tag that already exists, the existing tag will be overwritten.

This function must be called on init or earlier.

What it does

  • Gets a query var name by stripping the % signs from the name of the tag: trim($tag, ‘%’)
  • Calls $wp_rewrite->add_rewrite_tag() with the name, generated QV name and regex.
  • Adds the QV as a query var (again, this could be done by filtering query_vars but it might be nicer to add a function to the WP class that stores ‘extra’ QVs like above)


function add_rewrite_tag( $tag, $regex, $query = '' ) {
	// Validate the tag's name.
	if ( strlen( $tag ) < 3 || '%' !== $tag[0] || '%' !== $tag[ strlen( $tag ) - 1 ] ) {

	global $wp_rewrite, $wp;

	if ( empty( $query ) ) {
		$qv = trim( $tag, '%' );
		$wp->add_query_var( $qv );
		$query = $qv . '=';

	$wp_rewrite->add_rewrite_tag( $tag, $regex, $query );



User Contributed Notes

  1. Skip to note 3 content

    In the following examples, imagine a site has a custom taxonomy ‘location’ and all posts are assigned a location term like “Paris” or “Madrid”. We add a rewrite tag “%location%” to establish the location query var. We also add a rewrite rule so that an URL such as is properly handled.

    add_action('init', 'add_my_rewrites');
    function add_my_rewrites() {
        add_rewrite_tag('%location%', '([^&]+)', 'location=');

    Even though rewrite tags look just like permalink structure tags, if you try to use your rewrite tag in a permalink structure, the URLs generated by WordPress will look something like The proper term does not replace the rewrite tag as you might expect. To make your tag behave like a structure tag, use the “post_link” filter to replace the tag with the proper term.

    // Assign value to %location% rewrite tag
    add_filter('post_link', 'my_filter_post_link', 10, 2 );
    function my_filter_post_link( $permalink, $post ) {
        // bail if %location% tag is not present in the url:
        if ( false === strpos( $permalink, '%location%' ) ) {
            return $permalink;
        $terms = wp_get_post_terms( $post->ID, 'location' );
        // set location, if no location is found, provide a default value.
        if ( 0 < count( $terms ) ) {
            $location = $terms[0]->slug;
        } else {
            $location = 'timbuktu';
            $location = urlencode( $location );
            $permalink = str_replace('%location%', $location , $permalink );
        return $permalink;

    Anytime you change something related to the Rewrite API, don’t forget to flush the rewrite rules! This can be done without code by going to Permalink Settings and clicking Save Changes. You don’t actually need to make any changes on the settings screen.

  2. Skip to note 4 content

    (From Codex)
    The following will register a tag called ‘film_title’:

        function custom_rewrite_tag() {
            add_rewrite_tag('%film_title%', '([^&]+)');
        add_action('init', 'custom_rewrite_tag', 10, 0);

    This is particularly important when you are using rewrites with custom page templates.

    Retrieving the Value of a Rewritten URL
    With a rewrite tag defined, you can now retrieve the value of your rewritten querystring variables using WordPress’s $wp_query variable. To get the value of the above tag out of a rewrite, you could use the following in your page template:


    Note that using $_GET on a rewritten URL will not work, even if the rewrite includes the querystring variables. You must use $wp_query.

You must log in before being able to contribute a note or feedback.