When building a website with Craft CMS, there are numerous scenarios where you need to fetch the current page's full URL. Whether you are creating a 'Share on Twitter' button, setting up SEO canonical tags, or debugging your routing, knowing how to output the absolute URL is a fundamental skill for any Craft developer.

In this guide, we will explore the most efficient ways to retrieve the full URL in Craft CMS 3, 4, and 5, while also touching on legacy methods and specific use cases like handling query strings.

The Modern Standard: Craft 3, 4, and 5

If you are working on a modern Craft CMS installation, the most straightforward and recommended way to get the full, absolute URL of the current page is by using the request component of the Craft app object.

In your Twig templates, you can use the following snippet:

{{ craft.app.request.absoluteUrl }}

This property returns the complete URL, including the protocol (http or https), the domain name, the path, and any query strings that might be present (e.g., https://example.com/blog/my-post?utm_source=newsletter).

Why use absoluteUrl?

Using absoluteUrl is generally safer than manually concatenating strings because it relies on Craft's internal request handling. It automatically respects your site's configuration, ensuring that the protocol and hostname match what the server is currently processing.

Breaking Down the Request Object

Sometimes, you don't need the entire URL. You might only need the URI path or the hostname. The craft.app.request object (which maps to the yii\web\Request class) provides several properties that allow you to slice and dice the URL as needed.

1. The Path Only

If you only want the part of the URL that comes after the domain name, use pathInfo:

{{ craft.app.request.pathInfo }}

Example output: blog/my-post

2. The Host Info

To get just the protocol and the domain name without the path:

{{ craft.app.request.hostInfo }}

Example output: https://example.com

3. The Request URI

If you want the path and the query string, but not the domain name:

{{ craft.app.request.requestUri }}

Example output: /blog/my-post?s=craft-cms

Accessing the URL via PHP

If you are developing a custom Craft CMS plugin or a module, you might need to access the current URL within a PHP controller or service. You can access the same request component through the main Craft application instance.

You have two primary ways to write this in PHP:

// Using the getter method
$url = \Craft::$app->getRequest()->absoluteUrl;

// Using the property directly
$url = \Craft::$app->request->absoluteUrl;

Both of these will return the same string as the Twig equivalent, making it easy to pass the current URL into backend logic, such as logging or custom redirection rules.

Practical Use Cases

A common requirement is creating a link that allows users to share the current page on social media. Since these platforms require an absolute URL, you can generate the link like this:

<a href="https://www.facebook.com/sharer/sharer.php?u={{ craft.app.request.absoluteUrl | url_encode }}" target="_blank">
    Share on Facebook
</a>

SEO Canonical Tags

To prevent duplicate content issues, it is best practice to define a canonical URL in your <head> section. This tells search engines which version of a URL is the "master" copy.

<link rel="canonical" href="{{ entry.url ?? craft.app.request.absoluteUrl }}">

In this example, we prioritize the entry's defined URL but fall back to the current absolute request URL if the page isn't a standard entry (like a category page or a search results page).

Handling Legacy Craft 2 Sites

While most developers have migrated to Craft 3, 4, or 5, you may occasionally find yourself maintaining a legacy Craft 2 site. In Craft 2, the syntax was slightly different:

{# Basic URL in Craft 2 #}
{{ craft.request.getUrl() }}

{# Or using the property shortcut #}
{{ craft.request.url }}

If you needed to include the query string in Craft 2, you often had to concatenate the host info and the request URI manually:

{{ craft.request.getHostInfo() ~ craft.request.getRequestUri() }}

Frequently Asked Questions

Does absoluteUrl include the query string?

Yes, {{ craft.app.request.absoluteUrl }} includes the full query string (everything after the ?). If you need the URL without the query string, use {{ craft.app.request.hostInfo ~ '/' ~ craft.app.request.pathInfo }}.

How do I get the URL in a multi-site setup?

In a multi-site environment, craft.app.request.absoluteUrl will automatically return the URL for the specific site the user is currently browsing. Craft handles the site detection based on your @web alias and Site URL settings in the control panel.

Why am I seeing localhost in my URL?

If your URL is outputting localhost or an incorrect domain, check your @web alias in config/general.php or your Site URL settings in the Craft Control Panel. Craft relies on these configurations to generate accurate absolute URLs.

Wrapping Up

Retrieving the current page URL in Craft CMS is a simple task once you know your way around the craft.app.request object. For 99% of use cases, {{ craft.app.request.absoluteUrl }} is the only tool you'll need. It is clean, reliable, and works across all modern versions of the platform.

By understanding the different components of the request object—like pathInfo and hostInfo—you gain finer control over your templates, allowing you to build better SEO features and more robust social integrations.