URL Resolver
URL Resolver Configuration Reference
The JSON URL Resolver lets you define rules that compute URL paths for content and taxonomy entities without writing JavaScript. Rules are evaluated at request time and return one or more candidate paths ordered by priority. See for the application of the URL resolver in Experience: Dynamic URL Resolving
Top-level structure
Field | Type | Required | Description |
|---|---|---|---|
rules | array of Rule | yes | Ordered collection of resolver rules. All enabled rules whose condition matches are evaluated; results are sorted by priority descending. |
Rule
Field | Type | Required | Default | Description |
|---|---|---|---|---|
ruleId | string | yes | — | Unique identifier for the rule. Used in logs and test output. |
name | string | no | — | Display name shown in the editor UI. |
description | string | no | — | Free-text explanation. Useful for documenting non-obvious logic. |
enabled | boolean | no | true | Disabled rules are skipped entirely. |
priority | integer | no | 0 | Higher value = earlier in the result list when multiple rules match. Rules with equal priority appear in declaration order. |
condition | Condition | no | — | If omitted the rule matches every entity of the correct param type. |
pathBuilder | PathBuilder | yes | — | Defines how the URL path is assembled. |
Condition
Determines whether a rule applies to a given entity. All filters must pass (logical AND).
Field | Type | Required | Description |
|---|---|---|---|
paramType | "content" | "taxonomy" | yes | The entity type this rule applies to. A rule with "content" never matches a taxonomy and vice versa. |
filters | array of Filter | no | All filters must pass. An empty array (or omitting the field) means the rule matches every entity of the given paramType. |
Filter
Field | Type | Required | Description |
|---|---|---|---|
property | string | yes | Dot-notation path into the entity (see Resolvable properties). |
operator | string | yes | Comparison operator (see table below). |
value | string, string array, or null | depends on operator | The value to compare against. |
Filter operators
Operator | value type | Passes when |
|---|---|---|
equals | string | resolved property equals value (case-sensitive) |
notEquals | string | resolved property does not equal value |
in | array of strings | resolved property is one of the values in the array |
notIn | array of strings | resolved property is not in the array |
contains | string | resolved property contains value as a substring (case-insensitive) |
isNull | — (omit value) | resolved property is absent or null |
isNotNull | — (omit value) | resolved property is present and non-null |
PathBuilder
Assembles the URL path from an ordered list of segments.
Field | Type | Required | Default | Description |
|---|---|---|---|---|
prefix | string | no | "/" | Prepended verbatim before all segments. |
separator | string | no | "/" | Inserted between consecutive normal segments. Not used before propertySuffix segments (see below). |
segments | array of Segment | yes | — | Ordered list of path components. |
The final path is: prefix + segment[0] + separator + segment[1] + separator + ...
A propertySuffix segment is an exception: it is concatenated directly onto the preceding segment with no separator (see Segment: propertySuffix).
If segments is empty the path equals prefix (typically "/").
If any required segment cannot be resolved (e.g. a referenced property does not exist), the entire rule is silently skipped and produces no path.
Segments
Segment: literal
A fixed string value.
Field | Type | Required | Description |
|---|---|---|---|
value | string | yes | The exact text to include in the path. |
Example: { "type": "literal", "value": "presse" } contributes presse to the path.
Segment: property
Reads a value from the entity at the given dot-notation path.
Field | Type | Required | Description |
|---|---|---|---|
source | string | yes | Dot-notation path into the entity (see Resolvable properties). |
If the property is absent or null the rule is skipped (no path produced).
Segment: taxonomyChain
Resolves a taxonomy identifier to its full ancestor chain and joins them with /.
Field | Type | Required | Description |
|---|---|---|---|
source | string | yes | A path that resolves to a taxonomy identifier (typically taxonomies.<type>.identifier). |
The engine loads all ancestors of the resolved taxonomy and joins their identifiers with /, ordered from root to leaf. This produces a nested path like electronics/laptops/gaming.
If the identifier cannot be resolved or the taxonomy lookup fails the rule is skipped.
Segment: propertySuffix
Resolves a property value and concatenates it directly onto the preceding segment — no path separator is inserted before it. Fails the rule (like property) when the source property is absent.
Field | Type | Required | Description |
|---|---|---|---|
source | string | yes | Dot-notation path to the property value to append. |
Example: with a preceding property segment resolving to my-article and source resolving to 12345, the segment contributes 12345 concatenated directly: my-article12345.
Use literalSuffix segments before and after to add surrounding punctuation (see Segment: literalSuffix and the composition example).
Segment: literalSuffix
Appends a fixed string directly onto the preceding segment — no path separator is inserted before it. Always renders (cannot be made conditional).
Field | Type | Required | Description |
|---|---|---|---|
value | string | yes | The exact text to concatenate onto the preceding segment. |
Example: with a preceding property segment resolving to my-article, a literalSuffix with value = ".html" produces my-article.html.
Segment: datePart
Formats a date/timestamp property using a date/time pattern — useful for building year/month/day path segments from a publication date.
{ "type": "datePart", "source": "publicationDate", "format": "yyyy/MM/dd", "zone": "Europe/Berlin" }
Field | Type | Required | Description |
|---|---|---|---|
source | string | yes | Dot-notation path to a date/timestamp property. Currently only publicationDate (content) is supported . |
format | string | yes | A Java DateTimeFormatter pattern, e.g. yyyy/MM/dd. Use MM/dd (not M/d) for zero-padded values. May itself contain / — the resolved value is placed at this segment's position among the others, still joined to neighboring segments by pathBuilder.separator as normal. |
zone | string | no | IANA time zone id (e.g. Europe/Berlin) used to convert the underlying instant to a calendar date before formatting. Defaults to UTC when omitted. |
If the property is absent, not a valid date, or format/zone is invalid, the rule is skipped (like property).
Example: with publicationDate = 2024-05-03T22:30:00Z, format = "yyyy/MM/dd", and zone = "Europe/Berlin" (CEST, UTC+2), the segment contributes 2024/05/04.
Resolvable properties
The dot-notation paths used in filter property fields and segment source fields.
Content properties
Path | Description | Example value |
|---|---|---|
type.name | Content type | POST, BUNDLE, ISSUE |
id | Internal MongoDB ID | "64a1f2..." |
externalId | External identifier | "ext-42" |
name | Display name | "My Article" |
postType | Post type (POST content only) | "tests", "ratgeber", "page" |
bundleType | Bundle type (BUNDLE content only) | "magazine" |
publication.id | Publication ID | "pub-1" |
publication.name | Publication name | "My Magazine" |
publication.properties.<key> | Publication's custom property by key | publication.properties.slug -> "my-publication" |
properties.<key> | Custom property by key | properties.slug → "my-article" |
taxonomies.<type>.identifier | Identifier of the first taxonomy with the given type | taxonomies.category.identifier → "news" |
taxonomies.<type>.name | Name of the first taxonomy with the given type | taxonomies.author.name → "Jane Smith" |
taxonomies.<type>.type | Type of the first taxonomy with the given type | taxonomies.category.type → "category" |
taxonomies.<index>.identifier | Identifier of the taxonomy at the given 0-based index | taxonomies.0.identifier |
taxonomies.<index>.name | Name of the taxonomy at the given index | taxonomies.0.name |
Taxonomy properties
Path | Description | Example value |
|---|---|---|
identifier | URL-safe identifier | "essen-trinken" |
type | Taxonomy type | "category", "author", "tag" |
name | Display name | "Essen & Trinken" |
parentIdentifier | Identifier of the parent taxonomy, or null | "food" |
internalId | Internal MongoDB ID | "64b3e1..." |
properties.<key> | Custom property by key | properties.slug |
Complete examples
BUNDLE → /hefte/{slug}_{id}.html
literalSuffix and propertySuffix compose to build the _{id}.html part directly onto the slug with no / separator between them.
Produces /hefte/oeko-test-spezial-2024_42.html when slug = "oeko-test-spezial-2024" and id = "42". Fails (produces no path) when id is absent — use a lower-priority rule without the suffix segments as a fallback if needed.
Regular posts → /{category}/{slug}_{contentId}_1.html
Uses static_slug when present, falls back to slug via two rules at different priorities.
The -static variant (priority 2) fires only when static_slug is set; when it is absent its segment fails and the rule is silently skipped, leaving the base variant (priority 1) to fire. Both rules may fire simultaneously when static_slug is set — the higher-priority path is used as the canonical URL.
Category taxonomy → /{identifier}
Evaluation order and multiple paths
All enabled rules are evaluated against every request. A single entity can match multiple rules and receive multiple paths — this is intentional for canonical/alias URL patterns.
Results are returned ordered by priority descending. The first path in the list is treated as the canonical URL by consumers.
When a rule's path cannot be fully assembled (a required property is missing, a taxonomy lookup fails, etc.) that rule is silently dropped from the results. It does not cause an error.
When no config exists on the app, or the config has no rules, the engine returns nothing and the JS resolver is used as a fallback.