Skip to main content

Define a Selector Manually

Learn how Candu selectors work, when to use automatic vs manual selectors, and how to create stable CSS selectors to ensure your in-app content displays reliably.

Written by Jonathan Anderson

Selectors tell Candu exactly where to insert your content on a page. A selector is a string that identifies a specific HTML element in your page's DOM.

In most cases, you'll use Snapshots to define selectors. Snapshots automatically create selectors for you by analyzing your page structure. This is fast and works for the majority of placements.

However, automatic selectors aren't always reliable. If your page structure changes after you create the placement, or if your selector is dynamic, Candu may no longer be able to find that element. When Candu can't reliably find the element, your content won't display.

When to create a selector manually

You may want to define your own selector if:

  1. Dynamic CSS classes or IDs: When classes or IDs change from page view to page view, or from user to user.

  2. Shifting page structure: When sections of the page move around or aren’t consistently called out in the DOM.

Whenever possible, we recommend adding custom IDs or data attributes to your HTML to create stable selectors. But if you don’t have that flexibility, manual selectors are the next best option.

Features of Selectors

Candu selectors use standard CSS selector syntax with a few restrictions:

  • We don’t support the :nth-child operator, since it can become unstable when Candu elements are inserted into the DOM.

  • All other common selectors, combinations, and nesting rules work as expected.

Basic CSS Selectors

Here are the most common selectors you’ll use:

  • Class selector (.)
    Targets elements by their class name.

    .button-primary

    Matches any element with class="button-primary".

  • ID selector (#)
    Targets a single element by its unique ID.

    #welcome_page

    Matches the element <div id="welcome_page">…</div>.

More advanced selectors

You can also combine selectors to be more specific:

  • Multiple selectors on the same element

    #foo.example

    Targets an element with both id="foo"andclass="example".

  • Descendant selectors

    #foo .bar

    Targets any element with class="bar" that is nested inside the element with id="foo".

  • Type selectors

    #foo p

    Targets <p> elements inside the element with id="foo".

  • :nth-of-type()

    #list li:nth-of-type(2)

    Targets the second <li> inside #list.

Note: :nth-child() is not supported because it becomes unstable when Candu inserts elements into the DOM. Use :nth-of-type() instead.

Candu-Specific Selector

Candu also supports a custom extension:

  • :contains("text")

Useful when no stable ID or class is available, but element always contains unique text. It matches elements that contain the specified text anywhere inside them. Can be combined with any element type, class, or ID:

div:contains("Welcome") 
.sidebar:contains("Menu")
#header:contains("Dashboard")
button:contains("Get Started")
.nav-sidebar:contains("Menu")
.nav-menu li:contains("Home")

Note::contains("Example") is case sensitive and will not match example or EXAMPLE.

💡 Tip: Watch out for localization. If the text changes for different languages, the selector may no longer match.

How to Apply a Manual Selector in Candu

You can define selectors directly inside the Candu Editor in two ways:

Option 1: Placement Toolbox (fastest)

  1. Open the Candu Editor

  2. In the floating bar to the right, click Placements

  3. In the "Where will your content go?" section, click Edit next to HTML Selector

  4. Enter your selector (e.g. #welcome_page).

    Note: If you’re working on a snapshot, you’ll see updates in real time.

Option 2: Content Settings

  1. In the Candu Editor top bar, click Settings

  2. Go to Placements

  3. Either:

    • Click the ✏️ icon next to an existing placement to update its selector

    • Click Add a new placement to define a new one

  4. Enter your selector and save.

📌 Note: Selector changes take effect immediately. You do not need to republish your content after editing a selector

Testing Your Selector

Standard CSS selectors only: Browser methods such as document.querySelector() and document.querySelectorAll() accept standard CSS syntax. They do not understand Candu’s custom :contains("text") extension. Test that syntax using Candu’s placement matching or highlighting instead. A browser SyntaxError is not a “no matching element” result.

Test on the actual host page in the state where the element should appear. For example, open the relevant menu or modal first. For a standard CSS selector, you can also inspect matches in the browser:

  • Open your browser's developer tools (F12)

  • Use Console and type: document.querySelector('your-selector-here')

  • If it returns null, no element matched in that document at that moment. Check the page, open/closed UI state and loading state before changing the selector

👉 For more detailed troubleshooting: See our complete guide on Troubleshooting Selector Issues

Check that the selector finds the intended element

For standard CSS, document.querySelectorAll('your-selector-here').length shows how many elements match. Inspect the matches; the first match is not necessarily the intended target. Prefer a stable ID or data attribute and enough context to identify the element. A selector based on translated text or generated classes may change between users or page loads.

A match in a snapshot is evidence about that captured page, not proof that the same element exists on the live page. Check both the intended page state and the URL rules before saving a placement change.

Note on Combining Manual Selectors with URL Rules

Manual selectors work with URL targeting to create precise placement logic:

Example: Dashboard banner only on main dashboard page

  • Selector: #dashboard-header

  • URL rule: Exactly matches https://app.example.com/dashboard

Example: Feature announcement across product section

  • Selector: div:contains("products")

  • URL rule: Starts with /products

👉 Learn more about URL Targeting

Limitations

  • Selectors cannot target elements inside iframes or shadow DOM.

  • You cannot target Candu content. Selectors only apply to your page's existing HTML.

Need help? Reach out via chat or email us at [email protected].

Did this answer your question?