add_rewrite_rule( string $regex, string|array $query, string $after = 'bottom' )

Adds a rewrite rule that transforms a URL structure to a set of query vars.


Description Description

Any value in the $after parameter that isn’t ‘bottom’ will result in the rule being placed at the top of the rewrite rules.


Top ↑

Parameters Parameters

$regex

(string) (Required) Regular expression to match request against.

$query

(string|array) (Required) The corresponding query vars for this rewrite rule.

$after

(string) (Optional) Priority of the new rule. Accepts 'top' or 'bottom'.

Default value: 'bottom'


Top ↑

More Information More Information

add_rewrite_rule() allows you to specify additional rewrite rules for WordPress. It is most commonly used in conjunction with add_rewrite_tag() (which allows WordPress to recognize custom post/get variables).


Top ↑

Source Source

File: wp-includes/rewrite.php

function add_rewrite_rule( $regex, $query, $after = 'bottom' ) {
	global $wp_rewrite;

	$wp_rewrite->add_rule( $regex, $query, $after );
}


Top ↑

Changelog Changelog

Changelog
Version Description
4.4.0 Array support was added to the $query parameter.
2.1.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note 1 content
    Contributed by Anthony Eden

    Here is a simple example of how to register a new rewrite rule, and pass it off to a PHP file for rendering:

    1. Setup a rule:

    add_action( 'init',  function() {
        add_rewrite_rule( 'myparamname/([a-z0-9-]+)[/]?$', 'index.php?myparamname=$matches[1]', 'top' );
    } );
    

    2. Flush permalinks. Go to WP Admin > Settings > Permalinks > Save. This doesn’t happen automatically after you add this code

    3. Whitelist the query param:

    add_filter( 'query_vars', function( $query_vars ) {
        $query_vars[] = 'myparamname';
        return $query_vars;
    } );
    

    4. Add a handler to send it off to a template file:

    add_action( 'template_include', function( $template ) {
        if ( get_query_var( 'myparamname' ) == false || get_query_var( 'myparamname' ) == '' ) {
            return $template;
        }
    
        return get_template_directory() . '/template-name.php';
    } );
    
  2. Skip to note 2 content
    Contributed by tomasdev

    Things that were in WP Codex site and did not get migrated for whatever reason.

    NOTE: When using $matches[] to retrieve the values of a matched URL, capture group data starts at 1, not 0.

    IMPORTANT: Do not forget to flush and regenerate the rewrite rules database after modifying rules. From WordPress Administration Screens, Select Settings -> Permalinks and just click Save Changes without any changes.

  3. Skip to note 3 content
    Contributed by Samuel Elh

    A quick example: processing rules to make a subscribers page, hoping it helps.

    add_action('init', function() {
    
    	$page_id = 2; // update 2 (sample page) to your custom page ID where you can get the subscriber(s) data later
    	$page_data = get_post( $page_id );
    
    	if( ! is_object($page_data) ) { // post not there
    		return;
    	}
    
    	add_rewrite_rule(
    		$page_data->post_name . '/subscriber/([^/]+)/?$',
    		'index.php?pagename=' . $page_data->post_name . '&my_subscribers=1&my_subscriber=$matches[1]',
    		'top'
    	);
    
    });
    

    Now in your page template ( if you have one, or while filtering this custom page’s content ), you can get the displayed subscriber slug by calling get_query_var('my_subscriber'), but first, pass 'my_subscriber' to the query variables:

    add_filter('query_vars', function($vars) {
        $vars[] = "my_subscriber";
        return $vars;
    });
    
  4. Skip to note 4 content
    Contributed by iqbalbary

    Example to add rewrite rule query as optional,hope it helps.

    function custom_rewrite_rule() {
    	add_rewrite_rule('^nutrition/?([^/]*)/?','index.php?page_id=12&food=$matches[1]','top');
    }
    add_action('init', 'custom_rewrite_rule', 10, 0);
    

    The main things here is to add ? in the start of your regex. Like ?([^/]*)

    Now, you can set default value for optional query where you will use the query.

    $food = $wp_query->get( 'food' );
    if( isset($food) && !empty($food) ) {
    	$nutrition = $food;
    }else{
    	$nutrition = 'strawberry'; //default value
    }
    

    Now you will get the same result for http://example.com/nutrition/strawberry or http://example.com/nutrition/

  5. Skip to note 5 content
    Contributed by Akira Tachibana

    (From Codex)
    Basic Usage

    You can retrieve any page by specifying ID in URL as following:
    http://example.com/?p=95
    If you add the following rule to the functions.php file, you can provide custom formed URL to access.

    function custom_rewrite_basic() {
      add_rewrite_rule('^leaf/([0-9]+)/?', 'index.php?page_id=$matches[1]', 'top');
    }
    add_action('init', 'custom_rewrite_basic');

    NOTE: When using $matches[] to retrieve the values of a matched URL, capture group data starts at 1, not 0.

    IMPORTANT: Do not forget to flush and regenerate the rewrite rules database after modifying rules. From WordPress Administration Screens, Select Settings -> Permalinks and just click Save Changes without any changes.

    Now, you can access the same page as
    http://example.com/leaf/95

  6. Skip to note 6 content
    Contributed by Akira Tachibana

    (From Codex)
    Using Custom Templates with custom querystring

    Let’s assume you are creating a “Nutrition” page for showing nutritional information. This page uses a custom template and takes two variables, food and variety. Create a file named my-custom-template.php in your themes root directory as following:

    /**
     * Template Name: Nutritional Information
     */
    get_header(); 
    
    global $wp_query;
    echo 'Food : ' . $wp_query->query_vars['food'];
    echo '<br />';
    echo 'Variety : ' . $wp_query->query_vars['variety'];
    // ... more ...
    get_footer();

    Using this template, create a page. In Add New of Pages screen, select “Nutritional Information” from Template dropdown box. You may leave blank for title or contents. Click Publish to publish the page. Write down the ID of created page from All Pages screen. Move a mouse cursor on the page title to show the link information in status bar of Web browser. You will see the ID after the POST= in URL. In this example, assume the ID is 12.

    Use add_rewrite_tag() to make WordPress aware of custom querystring variables food and variety. Add the following code to the functions.php file,

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

    You can call the page as following:
    http://example.com/index.php?page_id=12&food=milkshake&variety=strawberry
    The page will show two values passed by querystring variables.

    Now, instead of passing ugly querystring variables to the page, you can set up a rewrite rule to create some custom pretty URLs. Add the following rule to the functions.php file and replace the page ID 12 by the ID that you investigated in above step. Don’t forget to click Save Changes in Permalinks Settings. (refer above IMPORTANT)

    function custom_rewrite_rule() {
        add_rewrite_rule('^nutrition/([^/]*)/([^/]*)/?','index.php?page_id=12&food=$matches[1]&variety=$matches[2]','top');
    }
    add_action('init', 'custom_rewrite_rule', 10, 0);

    User can access the same page with following URL:
    http://example.com/nutrition/milkshakes/strawberry/

  7. Skip to note 7 content
    Contributed by Akira Tachibana

    (From Codex)
    Using rewrite rules to redirect to scripts other than index.php

    The $redirect argument works slightly differently when redirecting to a custom PHP script because WordPress delegates these redirects to .htaccess instead of processing them itself. For this reason, querystring variables should be written like $1 instead of $matches[1]. Given we’re redirecting to a custom PHP script, adding the same rewrite rule from our previous example would look like this:

    function custom_rewrite_rule() {
        add_rewrite_rule('^nutrition/([^/]*)/([^/]*)/?','url/to/my/script.php?food=$1&variety=$2','top');
    }
    add_action('init', 'custom_rewrite_rule', 10, 0);
  8. Skip to note 8 content
    Contributed by Md Aminur Islam

    Rewrite rules with optional parameters.

    // siteurl.com/wpdocs-product-category/edit-product-category/43 for edit product category
    add_rewrite_rule(
    	'^wpdocs-product-category/([^/]*)/([^/]*)/?',
    	'index.php?pagename=wpdocs-product-category&wpdocs-pro-category-action=$matches[1]&wpdocs-product-cat-id=$matches[2]',
    	'top'
    );
    
    // Product Category Add Page
    // siteurl.com/wpdocs-product-category/add-product-category for add product category
    add_rewrite_rule(
    	'^wpdocs-product-category/([^/]*)/?',
    	'index.php?pagename=wpdocs-product-category&wpdocs-pro-category-action=$matches[1]',
    	'top'
    );
    

    Filters the query variables allowed before processing.

    add_filter( 'query_vars', function( $vars ) {
    	$vars[] = 'wpdocs-pro-category-action';
    	$vars[] = 'wpdocs-product-cat-id';
    	$vars[] = 'wpdocs-category-action';
    
        return $vars;
    } );
    

    Retrieve query parameters values

    $pro_category_action = get_query_var( 'wpdocs-pro-category-action' );
    $product_cat_id = get_query_var( 'wpdocs-product-cat-id' );
    

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