In a WordPress project I worked on recently I had to create some custom routing to turn a url with query strings into a pretty url path. We were pulling in data directly from an API relative to the profile page we were visiting so we couldn't use WordPress' built-in url structure. Here is an example of how we wanted our urls to look:


/user?username=zach => /user/zach

In the following example we'll create custom routing for user's profile page. Our route will look like this: /user/[username]. In our route the [username] will be replaced with the username of the user whose profile we are visiting.

With the exception the code we'll put in our user.php template, all this code can go in your theme's functions.php file.

Add routing

The first thing we'll do is add a rewrite rule to tell WordPress what our route will look like.


add_action('init', 'user_rewrite_rules');

function user_rewrite_rules() {

Register our username query parameter

Next we'll register our username query parameter so we can retrieve it later with the get_query_var function.


add_filter('query_vars', 'custom_user_query_vars');

function custom_user_query_vars($query_vars) {
    $query_vars[] = 'username';

    return $query_vars;

Create a php template for profile pages

Now that the routing is done we'll need to create a template that gets loaded when a profile page is visited. For this example we'll create a user.php file in the root of our theme's directory.

Once that file is created we can pull in some data for the user associated with the profile we're visiting.


//  get the username for the query
$username = get_query_var('username');

// user the $username to get the user info
$user = get_user_by('slug', $username);

<!-- output some info about the user -->
<h1><?= $user->first_name ?> <?= $user->last_name ?></h1>
<p><?= $user->user_email ?></p>

Conditionally load user template

Finally we need to load the template we just created when a profile is visited.


add_action('template_include', function ($template) {
    $username = get_query_var('username');

    if ($username !== false && $username !== '' ) {
        return get_template_directory() . '/user.php';

    return $template;

Wrapping Up

Now your routing should be all set up and when you visit /user/[username] you should see some info for the profile you're visiting. Obviously our template is super basic, so it's not going to look fancy but it's a good start.

text: zach patrick