Targeting on dynamic apps
Quick Access
What this page covers
Some applications make positioning harder than others. When the URL changes without a full page reload, or when CSS class names are regenerated on every build, Jimo loses track of the element an experience is attached to.
This page covers those two cases. For the position parameters, the element picker and the manual selector, start with Positioning.
Two problems, one symptom
Both show up in the dashboard the same way, an experience that does not display. They have different causes and different fixes.

SPA navigation
The URL changes client side without reloading the page, so a trigger based on the URL does not reliably re-fire
Trigger on the presence of an element, see SPA navigation
Dynamic CSS selectors
Class names and ids like header_stack_x7Gz or data-id="1xfr2w6" are regenerated on every build, so the selector Jimo memorized no longer exists
Target the stable part of the identifier, see Dynamic CSS selectors
SPA navigation
In a single-page application, moving from one view to another does not reload the page. Instead of triggering on the URL, trigger on the presence of an element that only exists on the target view.
Open the trigger settings. In your experience, go to Show on > On event.
Add an Element condition. Choose Is present, then select an element unique to the target view, a page title or a main container, not a global element like the header.
Save. The experience re-fires whenever that element appears in the DOM, independently of the URL.

The same Element condition is available in Steps Triggers to move between steps, and in Success Tracker events to build a no-code event you can reuse across several experiences.
Dynamic CSS selectors
In some cases, positioning in Jimo can be limited by how your website is structured, especially when elements are defined with dynamic CSS selectors.

If your UI uses dynamic identifiers that change constantly, Jimo's auto-selection will often break, and the element may be "lost".

Attribute selectors
Native CSS attribute selectors let you match only the stable part of a dynamic class or id. Enter them in the CSS Selector field of the Manual Selector.
[id^="prefix"]
id starts with prefix
[id^="mp-input"] matches mp-input-1234-control
[id$="suffix"]
id ends with suffix
[id$="control"] matches mp-input-1234-control
[id*="substring"]
id contains substring
[id*="mp-input"] matches anything-mp-input-1234
[id^="prefix"][id$="suffix"]
combines both, the most reliable
[id^="mp-input"][id$="control"]
The same syntax works on class, on data-* and on any other attribute. Combine it with the tag name to narrow the match down:

Full CSS reference: MDN attribute selectors.
Element text
When the element contains visible text, use the Element Text field of the manual selector, on its own or combined with a simple CSS selector like .btn, .menu or .title to refine matches if the text appears in several places.

Safety net
Enable Skip if target element not found on steps whose anchor may not always be present, so the rest of the experience continues instead of stalling.
Ask your developers
The durable fix costs one pass on the elements your experiences actually rely on. Share this with your technical team:
Selector cheat sheet

Stable identifier, the ideal
[data-test-id="save-btn"]
Class starts with
[class^="header_"]
Class contains
[class*="headerStack"]
Class ends with
[class$="_active"]
Tag plus partial class
button[class*="primaryCta"]
Descendant
nav [class*="menuItem"]
Two constraints combined
[id^="mp-input"][id$="control"]
Visible text, non-translated UI
.btn plus Element Text Save
Related pages
Last updated