Outbound request pipeline
Learn how the Umbraco outbound request pipeline works.
The outbound pipeline consists out of the following steps:
To explain these steps, the following content tree is used as an example:

1. Create segments
When a URL is constructed, Umbraco converts every node in the tree into a segment. Each published content item has a corresponding URL segment.
In the example above, "Our Products" becomes "our-products" and "Swibble" becomes "swibble".
Segments are created by the URL Segment Provider.
URL Segment Provider
The Dependency Injection (DI) container of an Umbraco implementation contains a collection of UrlSegmentProviders. This collection is populated during Umbraco startup. Umbraco ships with a 'DefaultUrlSegmentProvider', but custom implementations can be added to the collection.
When the GetUrlSegment extension method is called for a content item and culture combination, each registered IUrlSegmentProvider in the collection is executed in collection order. This continues until UrlSegmentProvider returns a segment value for the content. No further UrlSegmentProviders in the collection are executed after that point. If no segment is returned by any provider in the collection, the DefaultUrlSegmentProvider is used as a fallback. This ensures that a segment is always created.
To create a new URL Segment Provider, implement the IUrlSegmentProvider interface:
Each culture variation can have a different URL segment.
The returned string becomes the URL segment for the node. The value cannot contain the URL segment separator character /. A value such as 5678/swibble would create additional segments, which is not allowed.
Example
The following example adds the unique SKU or product reference of a product page to the existing URL segment.
The returned string becomes the native URL segment. There is no need for URL rewriting.
For the "swibble" product in the example content tree, ProductPageUrlSegmentProvider returns the segment swibble--123xyz, where 123xyz is the unique product SKU for the swibble product.
Register the custom UrlSegmentProvider with Umbraco using a composer:
The Default URL Segment Provider
The Default URL Segment Provider builds segments by checking for one of the following values, in this order:
A property with alias
umbracoUrlNameon the node. This is a convention-based way to give editors control of the segment name. With variants, this can vary by culture.The name of the content item, for example
content.Name.
The Umbraco string extension ToUrlSegment() is used to produce a clean, URL-safe segment.
2. Create paths
To create a path, the pipeline uses the segments of each node.
In the example, the "swibble" node receives the path /our-products/swibble. Using the ProductPageUrlSegmentProvider from above, the path becomes /our-products/swibble-123xyz.
Multiple sites in a single Umbraco implementation
In a multi-site scenario, an internal path such as /our-products/swibble-123xyz could belong to any of the sites, or match multiple nodes across multiple sites. In this case, additional sites have their internal path prefixed by the node ID of their root node. Any content node with a hostname defines a new root for paths.

Our Values
our-values
/our-values
Our Products
our-products
/our-products
Swibble
swibble-123xyz
/our-products/swibble-123xyz
Dibble
dibble-456abc
/our-products/dibble-456abc
Another Site
another-site
9676/
Their Values
their-values
9676/their-values
Paths can be cached. Scheme, domain, and current request cannot be cached.
Considerations when working with Hostnames
Domain without path:
www.site.comproduces1234/path/to/page.Domain with path:
www.site.com/dkproduces1234/dk/path/to/page.No domain specified:
/path/to/page.HideTopLevelNodeFromPathset totrue: the path becomes/to/page.
3. Creating URLs
The URL of a node consists of a complete URI: the Schema, Domain name, port, and path.
In the example, the "swibble" node has the URL: http://example.com/our-products/swibble.
URL generation is handled by the URL Provider. The URL Provider is called whenever a URL is requested in code, for example:
The DI container of an Umbraco implementation contains a collection of UrlProviders. This collection is populated during Umbraco startup. Umbraco ships with a DefaultUrlProvider, but custom implementations can be added to the collection. When .Url is called, each IUrlProvider in the collection is executed in collection order until a particular IUrlProvider returns a value.
DefaultUrlProvider
Umbraco ships with a DefaultUrlProvider, which maps the structure of the content tree to URLs out of the box. In Umbraco 15 and later, this is implemented as NewDefaultUrlProvider.
How the Default URL provider works
If the current domain matches the root domain of the target content, return a relative URL. Otherwise, return an absolute URL.
If the target content has one root domain, use that domain to build the absolute URL.
If the target content has more than one root domain, determine which one to use to build the absolute URL.
Complete the absolute URL with the scheme (HTTP or HTTPS). Use the scheme from the domain if one is specified; otherwise use the current request scheme.
If
addTrailingSlashistrue, add a trailing slash.Add the virtual directory.
If the URL provider encounters collisions when generating content URLs, it selects the first available node and assigns the URL to that node. The remaining nodes are marked as colliding and do not receive a generated URL. Fetching the URL of a node with a collision URL results in an error string that includes the node ID, for example #err-1094. This can happen when an umbracoUrlName property overrides the generated URL of a node, or when multiple root nodes exist without hostnames assigned.
Publishing an unpublished node with a conflicting URL may change the active node rendered at that URL. This occurs when the newly published node takes priority based on sort order in the tree.
Custom URL Provider
Create a custom URL Provider by implementing the IUrlProvider interface:
The UrlInfo object returned by GetUrl can contain a custom URL.
When implementing a custom URL Provider, consider the following:
Cache results where possible.
Handle schemes (HTTP vs HTTPS) and hostnames.
Inbound routing may require a matching
IContentFinder.
For small changes to URL generation logic, inherit from NewDefaultUrlProvider and override the GetUrl() virtual method rather than implementing IUrlProvider from scratch.
Example
This example replaces the default URL provider with a custom implementation, based on NewDefaultUrlProvider. The custom URL provider implements a new routing scheme for product pages.
The code below alters the outbound URL for product pages but does not provide matching inbound URL routing. This will break inbound routing, making the product pages unroutable.
To restore inbound routing, implement a custom content finder. See IContentFinder for more information.
Use a composer to replace the default URL provider with the custom implementation:
To use multiple URL providers, add them with multiple Insert calls. Umbraco cycles through all registered providers until one returns a non-null value. If all custom providers return null, Umbraco falls back to the default URL provider. The last provider added with Insert is the first to execute.
GetOtherUrls
The GetOtherUrls method is used only in the Umbraco Backoffice. It provides editors with a list of other URLs that also map to the node.
For example, the convention-based umbracoUrlAlias property allows editors to specify a comma-delimited list of alternative URLs for a node. A corresponding AliasUrlProvider is registered in the UrlProviderCollection to display this list in the backoffice Info panel.
GetPreviewUrlAsync
Implement this method when the URL provider supports a custom preview URL scheme.
A common use case is providing external preview environments for headless sites. See Additional preview environments support for a complete example.
Most custom URL providers do not support this. A default implementation returning null is sufficient in those cases:
Url Provider Mode
The URL Provider Mode specifies whether the URL provider produces absolute or relative URLs. Auto is the default.
The available modes are:
Change the default setting in the Umbraco:CMS:WebRouting section of appsettings.json:
See WebRouting config reference documentation for more information on routing settings.
Site Domain Mapper
The ISiteDomainMapper implementation is used in the IUrlProvider. It filters a list of DomainAndUri objects to return the one that best matches the current request.
Create a custom SiteDomainMapper by implementing ISiteDomainMapper:
The MapDomain methods receive the current request URI. Custom logic determines which domain to use for a site in the context of that request. The SiteDomainMapper receives the current URI and all eligible domains, and returns the single domain used by the URL Provider to construct the URL.
Only a single ISiteDomainMapper can be registered with Umbraco.
Register the custom ISiteDomainMapper using the SetSiteDomainHelper extension method:
Default SiteDomainMapper
Umbraco ships with a default SiteDomainMapper that supports grouping sets of domains together. In a multi-environment setup such as Umbraco Cloud, multiple domains may be configured for a single site. For example, live, staging, testing, and a backoffice domain. Each domain is set up as a Culture and Hostname entry inside Umbraco.

Without a SiteDomainMapper, editors see the full list of possible URLs for each content item across all configured domains:

This can lead to confusion. Clicking a staging URL may display content from a different environment or database.
To avoid this, use the default SiteDomainMapper's AddSite method to group related URLs together. Because the SiteDomainMapper is registered in the DI container, create a component to add the sites in the Initialize method:
Register the component with a composer:
When an editor visits the backoffice, the Links panel filters the displayed URLs to only those in the same site group as the current domain. An editor visiting via myproject-staging.euwest01.umbraco.io sees only the staging URL:

An editor visiting via myproject-dev.euwest01.umbraco.io sees only the dev and live URLs:

This is a grouping, not a one-to-one mapping. Multiple URLs can be added to a group. In the example above, an editor visiting via myproject.euwest01.umbraco.io (the live domain) would also see myproject-dev.euwest01.umbraco.io listed, as both belong to the dev group.
Grouping the groupings - BindSites
The SiteDomainMapper includes a BindSites method to bind different site groupings together:
Visiting the backoffice via myproject-dev.euwest01.umbraco.io now lists all domains from both the dev and the staging group.
Last updated
Was this helpful?