How to Get the Current Page URL in WordPress (PHP)

To get the current page URL in WordPress with PHP, combine the global $wp object with home_url(). This works on any page type (posts, pages, archives, categories, tags) and returns a clean, full URL:

global $wp;
$current_url = home_url( add_query_arg( array(), $wp->request ) );

echo esc_url( $current_url );

Below I’ll cover the variations you’ll actually need: just the slug, the URL with query string intact, the WordPress-native alternatives (get_permalink(), home_url(), site_url()), a plain-PHP fallback when you can’t use WordPress functions, and a shortcode you can drop into any post or page.


Method 1: Get the current URL with the global $wp object

This is the canonical WordPress-native way. It respects your permalink structure, works on any page type, and honors HTTPS and the site’s home setting without hardcoding anything.

function my_get_current_url() {
    global $wp;
    return home_url( add_query_arg( array(), $wp->request ) );
}

// Usage
echo esc_url( my_get_current_url() );

$wp->request holds the path after your domain (for example, about or blog/my-post). Wrapping it in home_url() prepends your site’s base URL, so the result is always a full, correctly-protocolled URL regardless of the environment.

Always pass output through esc_url() before printing it in HTML. It’s WordPress’s built-in function for escaping URLs safely.


Method 2: Get the current URL with query string

Method 1 strips the query string. If you want the URL including anything after the ? (e.g. ?page=2&s=keyword), use add_query_arg() with no arguments:

$current_url_full = home_url( add_query_arg( null, null ) );

echo esc_url( $current_url_full );

add_query_arg( null, null ) is WordPress shorthand for “the current URL plus its current query args.” Pair it with home_url() if you want the full, absolute URL rather than a relative one.

If you only care about one query parameter, use get_query_var() instead of parsing the URL manually. It works with both pretty permalinks and query-string params.


Method 3: Get just the current slug

If you only need the path (everything after the domain), the global $wp object has it ready:

global $wp;
$slug = $wp->request;  // e.g. "about" or "blog/my-post"

This returns whatever WordPress parsed as the request path, with no leading or trailing slashes. For deeper slug handling (post slug vs. path, terms, pagination), see the dedicated guide on getting the current page slug.


If you’re inside the WordPress loop or have access to a $post object, get_permalink() returns the URL of the current post or page. It’s the cleanest option for single-post templates:

// Inside the loop
$permalink = get_permalink();

// Or by ID
$permalink = get_permalink( 42 );

echo esc_url( $permalink );

The difference from Method 1: get_permalink() only works for posts and pages, not for archive, category, tag, or search result pages. Use global $wp when you need a universal solution.


Method 5: Plain PHP fallback (no WordPress functions)

Sometimes you need the current URL in a context where WordPress functions aren’t loaded (for example, a stand-alone PHP file you drop into your server). Use $_SERVER:

$protocol = ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' )
    ? 'https://'
    : 'http://';

$current_url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

echo esc_url( $current_url );

When WordPress is loaded, this is the less-safe option. $_SERVER values can be manipulated by request headers, and you’d need to sanitize them carefully. Stick with Method 1 unless you specifically need a zero-dependency snippet.


Method 6: Current URL as a shortcode

If you want to drop the current URL into a post or page without writing PHP in a template, register a shortcode. Drop this into your theme’s functions.php or a code snippets plugin:

add_shortcode( 'current_url', function() {
    global $wp;
    return esc_url( home_url( add_query_arg( array(), $wp->request ) ) );
} );

Now you can type [current_url] inside any post, page, or widget and it’ll output the current URL at render time.


home_url() vs site_url() vs get_permalink()

Three WordPress URL functions that look similar but do different things:

FunctionReturnsUse when
home_url()The site’s public home address (Settings → General → Site Address)Building URLs for visitors
site_url()Where WordPress itself is installed (WordPress Address)Building admin, wp-login, or WP core URLs
get_permalink()The URL of a specific post or pageInside the loop or when you have a post ID

For most themes, home_url() and site_url() return the same value. They diverge when WordPress is installed in a subdirectory but served from the root (for example, WP installed at /wp/ but the site lives at /).


Frequently asked questions

How do I get the current URL in WordPress?

Use the global $wp object with home_url(): $url = home_url( add_query_arg( array(), $wp->request ) );. This returns the full URL of whatever page WordPress is currently rendering (posts, pages, archives, tags, categories). Wrap the output in esc_url() before printing it.

How do I get the current URL in PHP without WordPress?

Use $_SERVER: combine the protocol ($_SERVER['HTTPS']), host ($_SERVER['HTTP_HOST']), and request URI ($_SERVER['REQUEST_URI']). When WordPress is available, prefer the $wp + home_url() approach because $_SERVER values can be manipulated via request headers and need extra sanitization.

What is the difference between home_url() and site_url()?

home_url() returns the public-facing address of your site (Settings → General → Site Address). site_url() returns where WordPress itself is installed (WordPress Address). They’re usually identical, but differ when WordPress lives in a subdirectory like /wp/ while the site is served from /.

How do I get just the slug of the current page?

Use $wp->request. It holds the path after your domain (for example, about or blog/my-post) with no leading or trailing slashes. For more slug variants (post slug alone, parent slug, term slug), see the dedicated slug guide.

How do I get the current URL with query parameters?

Call add_query_arg( null, null ) and wrap it in home_url(): $full = home_url( add_query_arg( null, null ) );. The double-null is WordPress shorthand for “the current URL including its current query args.” Use get_query_var() if you only need a specific parameter.

Can I display the current URL in a WordPress shortcode?

Yes. Register a shortcode in functions.php or a code snippets plugin: add_shortcode( 'current_url', function() { global $wp; return esc_url( home_url( add_query_arg( array(), $wp->request ) ) ); } );. Then use [current_url] inside any post, page, or widget.

Why is $_SERVER[‘REQUEST_URI’] not safe in WordPress?

It’s not automatically sanitized, so attackers can inject values via request headers or crafted URLs. If you output it without escaping, you risk reflected XSS. Always pass $_SERVER['REQUEST_URI'] through esc_url() or esc_attr(), or switch to the WordPress-native home_url() + $wp->request approach which handles sanitization for you.


Bottom line

Most of the time you want home_url( add_query_arg( array(), $wp->request ) ) wrapped in esc_url(). That pattern works on every page type, respects your site’s permalink structure and HTTPS settings, and sanitizes cleanly. Switch to get_permalink() when you’re inside the loop or have a post ID, and drop to plain $_SERVER only when WordPress functions aren’t available.

Related: how to get the current page slug, get the post ID, or browse the full WordPress code snippets library.

Picture of Andy Feliciotti

Andy Feliciotti

Andy has been a full time WordPress developer for over 15 years. Through his years of experience has built 100s of sites and learned plenty of tricks along the way. Found this article helpful? Buy Me A Coffee

One Response

Leave a Reply

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

WordPress Tips Monthly
Get the latest from SmartWP to your inbox.