In the transition from Drupal 7 to modern Drupal (versions 8, 9, and 10), many familiar procedural functions were replaced by service-oriented architectures. One of the most common tasks for developers—retrieving the current path or its alias—is a prime example of this shift. While drupal_get_path_alias() was the go-to in the past, modern Drupal provides several robust ways to handle paths depending on whether you are working in a controller, a theme, or a custom module.
Understanding how to correctly retrieve the current path is essential for generating breadcrumbs, setting active classes in menus, or performing logic based on the user's location within your site. In this guide, we will explore the various methods to get the current system path, the URL alias, and the full URI, including how to handle these tasks within Twig templates.
Retrieving the Internal System Path
In Drupal, every page has an internal system path (often looking like node/123 or taxonomy/term/456). This is the raw, un-aliased path that Drupal uses to route requests internally. If you need this specific identifier, you should use the path.current service.
To get the raw internal path programmatically, use the following code snippet:
$current_path = \Drupal::service('path.current')->getPath();
This will return a string starting with a forward slash, such as /node/1. This is particularly useful when you need to perform database lookups or logic that shouldn't change even if the site administrator updates the URL alias.
Translating Paths to URL Aliases
While system paths are great for logic, they are rarely what you want to show a user. For SEO and user experience, you likely want the path alias (e.g., /about-us instead of /node/1).
Since Drupal 8.8.0, the way we handle aliases has changed. The path.alias_manager service was deprecated in favor of the path_alias.manager service. Here is how you can retrieve the alias for the current page using the modern service:
// 1. Get the internal system path
$current_path = \Drupal::service('path.current')->getPath();
// 2. Use the alias manager to find the alias
$alias = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
It is important to note that getAliasByPath will return the system path itself if no alias exists. This makes it a safe, catch-all method for generating user-facing URLs.
Working with the Request Object
Sometimes you need more than just the path; you might need the full URI, including query strings or the domain. For this, Drupal provides access to the Symfony Request object. This is useful when you need to capture parameters like ?search=term or ?page=1.
The Request URI (With Query Strings)
If you want a direct representation of what the user sees in their browser address bar, use getRequestUri():
$current_uri = \Drupal::request()->getRequestUri();
Path Info (Without Query Strings)
If you want the path as requested by the user but want to strip away any query parameters, use getPathInfo():
$current_uri = \Drupal::request()->getPathInfo();
Full Absolute URL
If you need the full absolute URL (including https://example.com), the cleanest approach is to use the getUri() method on the request object:
$current_url = \Drupal::request()->getUri();
Using the Drupal Url Class
For many developers, working with the Url class is the most "Drupal-way" to handle current locations. This approach is highly flexible because it returns an object that can be converted to a string, checked for access, or manipulated further.
To get the current path as an aliased string via the Url class:
use \Drupal\Core\Url;
// Returns a relative path like /about-us
$url = Url::fromRoute('<current>')->toString();
If you need to force an absolute URL including the domain name:
$absolute_url = Url::fromRoute('<current>', [], ['absolute' => true])->toString();
If you need to preserve query strings while using the Url class, you can pass them from the request:
$url_with_query = Url::fromRoute('<current>', [], [
'query' => \Drupal::request()->query->all(),
'absolute' => true,
])->toString();
Getting the Current Path in Twig Templates
If you are working within a .html.twig file, you don't need to write PHP. Drupal provides built-in Twig functions to handle paths and URLs directly.
To get the URL of the current page in Twig:
{{ url('<current>') }}
If you only need the path (the part after the domain):
{{ path('<current>') }}
This is commonly used in templates for "Reload" buttons or canonical link tags:
<a href="{{ url('<current>') }}" class="button">{{ 'Refresh Page'|t }}</a>
Best Practices: Dependency Injection
While the examples above use static calls like \Drupal::service(), these should generally be avoided inside custom modules, especially within Controllers or Services. Instead, you should use Dependency Injection.
When defining a controller, inject the path.current and path_alias.manager services. This makes your code more testable and follows Drupal's architectural standards.
Example Controller Injection:
public function __construct(PathCurrentInterface $path_current, AliasManagerInterface $alias_manager) {
$this->pathCurrent = $path_current;
$this->aliasManager = $alias_manager;
}
Frequently Asked Questions
How do I get the current route name instead of the path?
Sometimes you don't want the path, but the underlying route (e.g., entity.node.canonical). You can get this from the route_match service:
$route_name = \Drupal::routeMatch()->getRouteName();
Why is my path alias not showing up correctly?
Ensure that the path_alias module is enabled (it is by default in standard installations). Also, remember that getAliasByPath() requires the internal system path starting with a slash. If you provide an incorrect system path, it will simply return the string you provided.
Can I get the current path in a preprocess function?
Yes. In a template_preprocess_page function, you can use the same \Drupal::service('path.current')->getPath() method to determine logic, such as adding specific CSS classes to the body tag based on the path.
Wrapping Up
Navigating paths and aliases in Drupal 8, 9, and 10 is straightforward once you understand the service-based approach. Whether you use the path.current service for internal logic, the path_alias.manager for SEO-friendly URLs, or Twig functions for your themes, Drupal provides a robust set of tools to ensure you can always find your way.
Always remember to check your Drupal version; if you are on a version later than 8.8, ensure you are using the path_alias.manager service to keep your codebase modern and deprecation-free.