Dynamic Routing
Purple Experience
In the Purple Experience, to allow more flexibility when defining routes for content, pages, taxonomies, collections and more, you can use the Dynamic URL Resolving functionality. There, you can control which URL belongs to a content, which view to show for what URL and inject content and other data into the view's context.
Key features are
- URL to View Mapping: Employs asynchronous resolvers for matching URLs to views, using pattern matching. Ideal for routing based on content type, taxonomy and other criteria.
- Data to Path Functionality: Maps content types to URLs, key for navigation elements like sitemaps and anchor tags.
- Data Resolver: Facilitates access to API objects for URL segments, aiding in managing complex data structures. Operates server-side.
- Redirect Handling: Enables both full path and segment-based redirects, crucial for URL restructuring and maintaining SEO. Includes features to prevent redirect loops.
The feature is mainly controlled by the file default/storefront/assets/scripts/url.resolver.js. When this file is created and has a default export, the dynamic routing feature is activated.
The url.resolver.js' default export must be an object with two fields: urlToViewResolvers and dataToPathResolver
This is an array of async resolvers, each matching a specific path pattern. If multiple resolvers match for a path pattern, they are executed in order, and the first one to return a result besides Not Found will be used. If no of the resolvers matches, the view is looked up by the path property from the views.json.
The resolving is based on https://github.com/pillarjs/path-to-regexp, so use the link to see possible pathPattern formats and how the match object can be structured.
Besides the match, you also get the resolvedData object, where each slug (path segments, split by "/") contains all the possible things this slug could be: content, taxonomy, collection, or a redirect.
It is up to the implementor of the url.resolver.js to select the right types from resolvedData, figure out which view to show and what data to inject into the view's context. While this requires more upfront work to set up and some JavaScript knowledge, it allows you to express route schemas that exactly match your need, including different views based on post type, assigned taxonomies and more.
There are three possible ViewResolverResults you can return from a resolver:
This function maps a content type to the path under which it should be accessible. Usages are opening the content with the openContent event action, generating anchor tags, site maps and other functionalities.
Besides the dataResolver, you get (exclusively) one of the four fields containing the data object to resolve a path for:
- content
- taxonomy
- collection
- publication
You return an object containing one or more paths this data should be accessible under.
The dataResolver exposes some methods you can use to easily get the Purple JS API objects relating to a slug match, resolving nested taxonomies and more.
As the code of the url.resolver.js is executed server side, using code and data that relies on client side information will fail.
For information how to configure redirects, read more at Purple Redirects
Using Purple Redirects which are published to the Content Cloud, you can redirect full paths or just individual segments, so that when you rename or restructure an URL, visitors automatically see the new page, and search crawlers too find the correct content.
On the Website, accessing a redirected URL will return a native HTTP redirect, with a custom status code or 301 as default.
On Apps or in case of SPA navigation, the Purple Experience frontend just replaces the URL in the user's address bar with the new one.
Redirects mapping a full path to another path are automatically supported by Experience. The requirements for the data are:
- they are published as type GENERIC
- they start with a slash without the brand
Example: redirect from https://my-domain.de/old/path to https://my-domain.de/new/cool/path you have to configure "/old/path" to "/new/cool/path".
You can also redirect to an external URL by adding a target stating with https://, but this should exclusively be used for external paths!
As the effect segment-based redirects have on the URL can vary from customer to customer, they require some manual work and are only supported when using the Dynamic Routing. But we provide an API to resolve recursive redirects automatically, so you only need to construct the final path of the last redirect target.
Below is an example on how to extend a resolver to handle arbitrary taxonomy redirects (replacements) of segments of the path.
The exact code depends a on your use case (e.g. is there a need to filter redirects for specific redirectTypes, is the last entry a content or taxonomy, and more).
Redirect loops are automatically caught by dataResolver.findFinalRedirect(...) which throws an error, so you shouldn't catch this call to allow the Purple Experience to handle the infinite redirect loop case.
Example Redirect handling for a two-resolver-setup; 1. <...optional taxonomy slugs>/<post slug> 2. <...taxonomy slugs>
When using the preview functionality (while writing / editing an article) in the Purple Hub you will always get a url which is similar to this: /read/article?preview=true&content=someContentID which is different to the usual <taxonomy slugs>/<post slug>. To preview the proper page with the correct context / data (usually pathPattern: '/:segmentSlugs+') you will need a redirect which can be configured as in the following example, the important part is the pathPattern: '/read/article'
Open Content event actions automatically use the content if present in the context.
Then, it will generate the URL belonging to that content using the DataToPathResolver (or in case of PFG issues the corresponding fixed URL) and open it. In case of issue/content components, they will be wrapped in an anchor tag to improve SEO performance.