Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk12 min

How to Get URL Parameters in WordPress: GET, Query Vars, and REST API

A practical WordPress guide to reading query strings, registering custom query variables, handling REST parameters, safely generating URLs, and troubleshooting missing values.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a URL such as https://example.com/offers/?campaign=spring&item=42, PHP exposes the query-string values in $_GET. If the value is meant to participate in WordPress’s main query, register the name with the query_vars filter and read it with get_query_var(). Inside a REST API callback, use the WP_REST_Request object instead of reaching directly into superglobals.

Whichever API you choose, treat the value as untrusted input: validate it for the expected type or allowlist, sanitize it for the destination, and escape a generated URL when you print it. The examples below cover front-end pages, custom query variables, REST routes, URL construction, and the common reasons a parameter appears to disappear.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the right WordPress API first

A query parameter is the part of a URL after the first question mark. In ?campaign=spring&item=42, the keys are campaign and item; their values are spring and 42. The same-looking URL can enter WordPress through different routing contexts, so the best reading method depends on what you are building.

Situation Read it with Important condition
Ordinary PHP handling a front-end request $_GET Check that the key exists, unslash the value, then validate and sanitize it.
A value that should be part of the WordPress main query get_query_var() Register a custom name through the query_vars filter first.
A custom REST API route WP_REST_Request Read query, path, body, or JSON parameters from the request object and define route arguments where possible.
Creating a link that carries parameters add_query_arg() Build the URL with WordPress’s helper, then escape it at output because the helper does not escape automatically.

Do not assume that get_query_var() is a safer spelling of $_GET. They serve different layers. WordPress’s reference notes that get_query_var() reads values recognized by WP_Query; an arbitrary custom key is not recognized until you register it.

Read a basic query parameter with $_GET

Use this pattern when a normal page, template, shortcode, or plugin callback needs a value from the current URL:

$campaign = isset( $_GET['campaign'] )
    ? sanitize_text_field( wp_unslash( $_GET['campaign'] ) )
    : '';

wp_unslash() removes the slashes WordPress adds to request data, and sanitize_text_field() removes or normalizes text that does not belong in a plain single-line string. The fallback makes the variable an empty string when the visitor did not supply campaign. Never print the raw superglobal directly into HTML.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Validate according to the value’s meaning

Sanitizing text is not enough when the application expects a number, date, email address, or one of a small set of choices. Validation answers whether the value is acceptable; sanitization prepares an accepted value for a particular use. Neither operation grants permission to view or change protected data.

$item_id = isset( $_GET['item'] )
    ? absint( wp_unslash( $_GET['item'] ) )
    : 0;

$allowed_views = array( 'grid', 'list' );
$view = isset( $_GET['view'] )
    ? sanitize_key( wp_unslash( $_GET['view'] ) )
    : 'grid';

if ( ! in_array( $view, $allowed_views, true ) ) {
    $view = 'grid';
}

For an identifier, reject zero or an ID that the current user is not allowed to access before loading the record. For a date, parse the expected format and reject impossible dates rather than silently converting them. For an email, use an email-specific validator and still apply your application’s ownership or permission checks.

Understand repeated keys and arrays

A URL can contain a repeated key, such as ?tag=php&tag=wordpress, or an explicitly named array such as ?tag[]=php&tag[]=wordpress. PHP’s parsing behavior differs between those forms, so decide whether your endpoint accepts one value or a list. If a list is allowed, verify that the result is actually an array, sanitize every member, limit its length, and reject unexpected nesting.

$tags = isset( $_GET['tag'] ) ? wp_unslash( $_GET['tag'] ) : array();
$tags = is_array( $tags ) ? $tags : array( $tags );
$tags = array_map( 'sanitize_key', $tags );
$tags = array_slice( array_values( array_unique( $tags ) ), 0, 20 );

Do not use a query parameter as an authorization mechanism. A value such as user_id=17 is merely a request for a record; authorization must be checked against the logged-in user and the object’s capabilities.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use get_query_var() for a registered WordPress query variable

get_query_var() is appropriate when a custom value should be available through the main WordPress query, alongside built-in variables used by templates and conditional tags. Register the name before reading it:

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

$campaign = get_query_var( 'campaign', '' );

The official get_query_var() reference documents this behavior: the function retrieves variables from WP_Query, so an unregistered custom name returns the default rather than the URL value. Put the filter in code that loads on the request, such as a plugin or an always-loaded theme file. Registering the variable after the main query has already been parsed will not retroactively make the value part of that query.

Use a query variable in a template

Suppose the visitor opens /offers/?campaign=spring. After registering campaign, a template can read it and then apply the same validation rules used for $_GET:

$campaign = sanitize_key( get_query_var( 'campaign', '' ) );
$campaigns = array( 'spring', 'summer' );

if ( ! in_array( $campaign, $campaigns, true ) ) {
    $campaign = '';
}

The second argument to get_query_var() is a default, not a validator. It prevents an undefined value from becoming a notice, but it does not constrain what a visitor can send. Keep custom names distinctive and avoid colliding with WordPress’s existing query variables.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When direct $_GET is the better choice

If the value is only an input to a small piece of PHP and does not need to influence the main query, using $_GET is simpler. Registering every temporary filter, sort, or tracking value as a query variable adds unnecessary coupling to WordPress’s routing layer. Choose get_query_var() when integration with the main query is the reason you need the parameter, not merely because it is available.

Read parameters in a WordPress REST API endpoint

REST callbacks receive a WP_REST_Request. Its methods expose values from the URL path, query string, form-encoded body, and JSON body. A minimal callback looks like this:

function my_endpoint_callback( WP_REST_Request $request ) {
    $genre = $request->get_param( 'genre' );

    return rest_ensure_response( array(
        'genre' => $genre,
    ) );
}

The REST API handbook explains parameter access in its Requests documentation. Reading through the request object keeps the callback aligned with REST routing and avoids assumptions about which PHP superglobal contains the value.

Register route arguments with validation and sanitization

For a production endpoint, describe accepted arguments in the route definition. WordPress can run a validation callback before the main callback and a sanitization callback on accepted input:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
add_action( 'rest_api_init', function () {
    register_rest_route( 'catalog/v1', '/books', array(
        'methods'  => WP_REST_Server::READABLE,
        'callback' => 'catalog_books_callback',
        'args'     => array(
            'page' => array(
                'default'           => 1,
                'sanitize_callback' => 'absint',
                'validate_callback' => function ( $value ) {
                    return (int) $value > 0;
                },
            ),
            'genre' => array(
                'sanitize_callback' => 'sanitize_key',
                'validate_callback' => function ( $value ) {
                    return in_array( $value, array( 'history', 'science' ), true );
                },
            ),
        ),
    ) );
} );

function catalog_books_callback( WP_REST_Request $request ) {
    $page  = $request->get_param( 'page' );
    $genre = $request->get_param( 'genre' );

    return rest_ensure_response( array(
        'page'  => $page,
        'genre' => $genre,
    ) );
}

Use get_param() when the same name may come from more than one request source. Use a more specific request method when your contract requires one source, such as a path parameter or JSON body. Keep the route schema and callback expectations in agreement: a callback should not quietly accept a type or value that the route definition rejects.

Path, query, body, and JSON values

A route such as /catalog/v1/books/42 can define 42 as a path argument, while ?genre=science is a query argument. A POST request may carry form data or JSON in its body. The request object provides methods for these sources, so a callback can distinguish an identifier in the path from filters in the query and fields in the submitted document.

Do not echo a request value into a response merely because it was accepted. Enforce authentication, authorization, rate limits, and object-level permissions appropriate to the endpoint. Validation makes input well-formed; it does not make an operation safe for every caller.

Build parameterized URLs with add_query_arg()

When your code needs to create a link, use WordPress’s URL helper rather than manually concatenating question marks and ampersands:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$url = add_query_arg(
    array(
        'campaign' => 'spring',
        'item'     => 42,
    ),
    home_url( '/offers/' )
);

echo '<a href="' . esc_url( $url ) . '">View offer</a>';

add_query_arg() handles an existing query string and encodes values for the URL. It can accept an associative array, a single key and value, or a URL that already contains parameters. The helper does not decide whether the final URL is safe to print. WordPress states: Important: The return value of add_query_arg() is not escaped by default.

Escape at the output context

Escape the completed URL where it is rendered, as in esc_url( $url ) for an HTML link. Do not escape a URL early and then continue manipulating it as if it were raw data; repeated transformations can alter the value. If a URL is used in a different context, use the escaping function appropriate to that context.

Approach Existing query string Encoding Output safety
Manual concatenation Easy to break by adding a second ? or losing an existing key You must encode each value correctly You must still escape the final URL
add_query_arg() Designed to add or replace query arguments WordPress performs URL argument handling Not escaped automatically; call esc_url() when printing

Preserve or remove existing values deliberately

If the current URL already has a parameter, passing a new value with the same key replaces it. That is useful for pagination and filters, but it can also carry tracking or state values farther than intended. Build a fresh base URL when you want a clean link, and explicitly remove keys when your application should not preserve them.

Why get_query_var() is empty

An empty result is usually a routing or registration issue rather than a PHP failure. Work through these checks in order.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Inspect the complete URL. Confirm that the parameter appears after ?, that additional parameters use &, and that the spelling and capitalization exactly match the key your code reads.
  2. Confirm registration. A custom name read with get_query_var() must be added through the query_vars filter. Verify that the filter is loaded for this request and that the variable is not being removed by another filter.
  3. Check request timing. Read the query variable after WordPress has initialized the main query. Code that runs before query parsing may not see the final value.
  4. Use the matching API. A REST callback should read from WP_REST_Request; a value needed only by a PHP template can be read from $_GET after validation.
  5. Test encoding. Spaces, ampersands, plus signs, percent-encoded characters, and non-ASCII text can change how a server parses the value. Generate test links with add_query_arg() instead of hand-building them.
  6. Check redirects and caches. A canonical redirect, page cache, reverse proxy, security plugin, or application redirect may remove or rewrite a query string before your code runs. Compare the browser’s final URL with the original link and test an uncached request in development.
  7. Review rewrite and permalink settings. Flush permalinks only when you have changed rewrite rules; repeatedly flushing on every request is unnecessary and can hurt performance.

For temporary development diagnostics, log the validated shape of a value rather than dumping the whole request. Never print raw input into the page or leave sensitive request data in production logs.

When REST query parameters never reach WordPress

Sometimes the callback is correct but the web server routes the request incorrectly. WordPress’s REST API FAQ identifies Nginx try_files configuration as one cause of query parameters not reaching WordPress. The fallback must preserve the original arguments; the documented pattern is:

try_files $uri $uri/ /index.php$is_args$args;

The exact Nginx configuration belongs in the server block for the site, and changes should be tested and reloaded according to your hosting setup. The significant part is $is_args$args, which carries the query string when one exists. If the server instead falls back to /index.php without the arguments, WordPress receives the route but not values such as ?genre=science.

Also check proxy rules, redirects that normalize URLs, and security layers that reject or strip unusual keys. Compare a direct request to the origin with the public URL only in a controlled environment; do not bypass production security controls for a quick test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Validation, sanitization, and escaping checklist

  • Presence: Decide whether the parameter is optional. Supply a safe default or return a clear error when it is required.
  • Type: Convert integers with an integer-specific function, validate dates against the format you document, and reject values outside sensible bounds.
  • Allowlist: For modes, sort orders, campaigns, and status values, accept only the documented choices.
  • Structure: If arrays are supported, validate every element and cap the number and size of elements.
  • Authorization: Check the current user’s capability and the target object’s ownership. A valid parameter is not proof that the caller may use it.
  • Output: Escape for the destination context. Use esc_url() for a generated HTML URL and the appropriate escaping function for text, attributes, JavaScript, or SQL contexts.
  • Privacy: Do not place passwords, access tokens, personal records, or other secrets in query strings. URLs can appear in browser history, server logs, analytics, referrers, screenshots, and caches.
  • Observability: Log only what you need for diagnosis, remove sensitive values, and disable verbose request logging after development.

Complete front-end example

The following pattern registers a campaign variable, validates it, and creates a link to another offer while preserving safe URL handling:

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

function current_campaign() {
    $campaign = sanitize_key( get_query_var( 'campaign', '' ) );
    $allowed  = array( 'spring', 'summer' );

    return in_array( $campaign, $allowed, true ) ? $campaign : '';
}

$campaign = current_campaign();
$offer_url = add_query_arg(
    array(
        'campaign' => $campaign,
        'item'     => 42,
    ),
    home_url( '/offers/' )
);

if ( $campaign ) {
    echo '<a href="' . esc_url( $offer_url ) . '">View campaign offer</a>';
}

The allowlist prevents arbitrary campaign names from changing the page’s behavior. The link is generated from a known site URL, and escaping happens only when the final value is inserted into the href attribute.

Testing parameter handling

Test each route with absent, valid, invalid, repeated, encoded, and unexpectedly large values. A small matrix catches more defects than testing only the happy path:

Case Example Expected behavior
Missing optional value /offers/ Use the documented default.
Valid scalar ?item=42 Convert and accept the integer after authorization.
Invalid type ?item=abc Reject it or return the safe invalid-value behavior; do not query an unintended record.
Encoded text ?campaign=spring%20sale Decode, then apply the correct validation and sanitization rules.
Unexpected list ?item[]=1&item[]=2 Reject it when a scalar is required, or process it under an explicit array contract.
REST body and query together ?page=2 with a JSON body Read each field from the intended request source and apply route validation.

For a REST endpoint, verify the HTTP status, response shape, and error message as well as the returned value. For a front-end page, inspect the final rendered link and confirm that the browser preserves the intended encoding. Include tests behind redirects and with the site’s normal cache and proxy path, because a request that works at the origin can still fail at the public URL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Practical decision guide

  1. Is this a normal page request and you only need one input? Read $_GET, unslash it, validate it, and sanitize it for use.
  2. Should the value participate in WordPress’s main query? Register the key with query_vars, then call get_query_var() after query initialization.
  3. Are you inside a REST callback? Define route arguments and read values from WP_REST_Request.
  4. Are you generating a link? Use add_query_arg() with a known base URL and call esc_url() at output.
  5. Does the value vanish only in production? Inspect redirects, caches, proxies, security filters, rewrite settings, and the web server’s argument-preserving fallback.

These choices keep URL parsing, WordPress routing, REST contracts, and HTML output in their proper layers. The result is code that behaves predictably for ordinary links, custom query variables, and API clients without treating untrusted URL data as trusted application state.

Frequently Asked Questions

Are URL parameter names case-sensitive in WordPress?

Yes. Treat parameter names as exact identifiers and use one documented spelling and capitalization everywhere. A link using Campaign will not reliably match code reading campaign.

Can a URL fragment be read with $_GET?

No. The portion after # is handled by the browser and is not sent in the HTTP request. Use a query parameter or send the value through client-side code if the server must receive it.

Should I put an authentication token in a query string?

No. Query strings can be retained in browser history, logs, analytics, referrers, and caches. Use the authentication mechanism defined by your application or API, and keep authorization checks separate from parameter validation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

SaleBestseller No. 2
Bestseller No. 3
SaleBestseller No. 4
Bestseller No. 5

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.