What is a Query Variable in WordPress?
A query variable is a named value WordPress uses when resolving a request or building its database query (WP_Query) to decide which content to load. Public query variables travel in URLs, like p in example.com/?p=123, which loads post ID 123; rewrite rules and code set others internally. Custom public variables read from a request must be registered first.
More About Query Variables
WordPress reads query variables from a URL to decide which query to run against the database. The plain permalink setting builds its URLs from exactly one of them. Plain is the fallback rather than what you'll usually see: since WordPress 4.2, the installer tries pretty permalinks during setup and falls back to query-string permalinks only when they don't work.
In https://example.com/?p=123, p is the query variable and 123 is its value: the post's unique ID in the database. Remove the value and WordPress ignores the empty parameter and serves the homepage. Point it at an ID that doesn't exist and WordPress returns a 404 error instead.
How WordPress uses query variables
WordPress keeps an allowlist of public query variables that WP_Query, the class WordPress uses to fetch content from the database, recognizes. Developers usually call them query vars. A parameter only does something when its key is on that list, and the get_query_var() function only retrieves those recognized variables. Common ones include:
- p: loads a post by its ID.
- page_id: loads a page by its ID.
- s: runs a search for the given term.
- cat: loads a category archive by category ID.
- paged: picks which page of an archive to show.
Query variables don't have to appear in the address bar. With pretty permalinks enabled, WordPress's rewrite rules translate a clean URL like /sample-post/ into internal query variables before the query runs, which is why the ?p=123 form keeps working after you switch permalink structures. Developers also set query variables directly in code when they build a custom query, so those never show up in a URL at all.
Query variable vs. query string vs. URL parameter
The three terms nest inside one another:

- A query string is everything after the ? in a URL, such as ?p=123&preview=true.
- A URL parameter is one key=value pair inside that string, like p=123.
- A query variable is a parameter key WordPress recognizes and acts on when it builds the page.
Every query variable can travel in a URL as a parameter, but not every parameter is a query variable. Add ?foo=bar to a WordPress URL and nothing changes, because WordPress ignores keys it doesn't recognize.
Registering custom query variables
Making WordPress read your own variable takes two steps. First, hook the query_vars filter and add your key to the array it passes:
function myplugin_query_vars( $qvars ) {
$qvars[] = 'city';
return $qvars;
}
add_filter( 'query_vars', 'myplugin_query_vars' );
Second, read the value with get_query_var( 'city' ). On a request like /?city=portland, that call now returns portland. Registration only tells WordPress to parse the key; it doesn't make the value safe. Anything that arrives in a request is user-controlled, so validate or sanitize it before your code acts on it.
Skipping registration causes the most common bug with this term: the custom variable sits right there in the URL, yet get_query_var() returns nothing, because WP_Query only knows its public query variables. If a value you expect keeps coming back empty, register the key first, then read it. Registration covers the query-string form only; to serve a clean path like /city/portland/, you also need to add a rewrite rule that maps that URL onto your variable.
Frequently Asked Questions
- Because the variable isn't a registered public query variable, get_query_var() falls back to its default return value, an empty string. Register the key through the query_vars filter and WordPress will parse it. You can also pass a second argument to get_query_var() to set your own default.
- Use get_query_var() for anything WordPress routes. $_GET reads raw request parameters straight from the URL, while get_query_var() reads the values WP_Query has already parsed and recognized, so it works with pretty permalinks. Reach for $_GET only for parameters WordPress doesn't manage.
- paged holds the page number on archives, like your blog index. page holds the reader's position inside a single post split with the nextpage Quicktag, and it's the variable to use for pagination on a static front page.
Powerful WordPress Hosting
Reliable, lightning-fast hosting solutions specifically optimized for WordPress. Find the perfect plan for you by clicking below.
WordPress Hosting Plans