# Understanding Ego‑Lite Snapshot Output Format and Using loc= Values

> Learn Ego-Lite snapshot output formats and use resilient loc= values like css, xpath, text, role, and href to navigate DOM changes effectively.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: api-reference
- Published: 2026-07-28

---

**Ego‑Lite’s `page.snapshot()` returns an HTML string with stable `@N` reference markers, while `page.snapshotRaw()` produces a structured object containing `content` and `refs` properties, and `loc=` values provide resilient locators using prefixes like `css:`, `xpath:`, `text:`, `role:`, and `href:` that survive DOM changes and page navigations.**

Ego‑Lite is a browser automation framework designed for AI agents requiring stable interaction primitives. Understanding the **snapshot output format** and how to leverage **`loc=` values** is essential for building scripts that withstand page reloads and DOM mutations. These mechanisms are implemented across the core driver files and provide the foundation for reliable element resolution.

## Snapshot Output Format in Ego‑Lite

Ego‑Lite provides two primary methods for capturing the current state of a webpage, each serving different use cases within the automation lifecycle.

### Human‑Readable HTML with @N References

The `page.snapshot()` method returns a string containing the page’s HTML snapshot with embedded **`@N`** reference markers. These markers provide stable numeric identifiers for DOM elements that can be referenced during the current session. According to the library’s format registry in **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)** (lines 402‑423), this method is optimized for debugging and visual inspection rather than programmatic parsing.

### Structured Raw Output via snapshotRaw()

For programmatic access, `page.snapshotRaw()` returns an object with two top‑level properties:

- **`content`** – A string containing the full HTML snapshot with embedded `@N` markers.
- **`refs`** – An array of reference objects describing DOM elements addressable via their numeric IDs.

This structured format is generated in **[`src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/observe.ts)** and declared in **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)**. The `refs` array enables precise element targeting without re‑querying the DOM, though these references are short‑lived compared to `loc=` locators.

## Understanding loc= Values and Locator Syntax

**`loc=`** values represent the preferred mechanism for creating stable, reusable locators that survive DOM changes and page navigations. Unlike raw `@N` references that expire after navigation, `loc=` strings are resolved dynamically against the current DOM each time they are used.

When a `loc=` string is passed to helpers like `page.click()`, `page.elementCenter()`, or `page.waitForSelector()`, the **element resolver** (implemented in **[`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)**) parses the string, evaluates it against the DOM, and returns the corresponding element or its reference ID. This mechanism provides **transient‑safe** resolution: if an element is temporarily unavailable, the resolver throws an `ElementResolutionError` with a `transient` flag, enabling retry logic.

### Supported Locator Prefixes

The element resolver supports five distinct locator prefixes, each targeting different DOM attributes:

- **`css:`** (default) – Standard CSS selector syntax. Example: `loc=div.article` or `loc=css:.nav-button`
- **`xpath:`** – XPath expressions for complex traversal. Example: `loc=xpath=//button[text()="Submit"]`
- **`text:`** – Case‑sensitive visible text search. Example: `loc=text=Login`
- **`role:`** – ARIA role selectors for accessibility. Example: `loc=role=button`
- **`href:`** – URL‑based selection for anchor tags. Example: `loc=href=/contact`

If no prefix is specified, the resolver defaults to CSS selector mode.

## Practical Examples of Using loc= Locators

The following examples demonstrate how to capture snapshots and use `loc=` values with methods exposed in **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)**:

```javascript
// Capture raw snapshot for debugging structured data
const snap = await page.snapshotRaw();
console.log(snap.content);   // HTML string with @N refs
console.log(snap.refs);      // [{ id: 12, locator: 'loc=css:.button', ... }]

// Click a link using URL-based locator
await page.click('loc=href=/pricing');

// Wait for element containing specific text
await page.waitForSelector('loc=text=Welcome back');

// Get center coordinates using explicit CSS prefix
const center = await page.elementCenter('loc=css=.hero-image');
console.log(center); // { x: 345, y: 210 }

```

## Summary

- **`page.snapshot()`** returns human‑readable HTML with `@N` markers defined in [`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts).
- **`page.snapshotRaw()`** provides a structured object with `content` (HTML string) and `refs` (element array) properties.
- **`loc=` values** use prefixes (`css:`, `xpath:`, `text:`, `role:`, `href:`) to create stable locators that survive navigation.
- The **element resolver** in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) handles dynamic resolution and throws `ElementResolutionError` with a `transient` flag for retryable failures.
- These mechanisms are exposed to agent scripts through **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)**.

## Frequently Asked Questions

### What is the difference between @N references and loc= locators?

`@N` references are numeric IDs embedded in HTML snapshots that point to specific DOM elements at the time of capture, but they become invalid after page navigation. **`loc=` locators** are string queries that resolve dynamically each time they are used, making them resilient across multiple rounds and page changes.

### How do I handle transient errors when resolving loc= values?

When an element is temporarily unavailable, the resolver in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) throws an `ElementResolutionError` with a `transient` property set to `true`. You should wrap your calls in retry logic that catches this specific error and re‑attempts the resolution after a brief delay.

### Which source files define the snapshot helpers and locator resolution?

The method signatures are declared in **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)** (lines 402‑423), the raw snapshot implementation resides in **[`src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/observe.ts)**, and the locator parsing logic is contained in **[`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)**. Public exposure to scripts occurs through **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)**.

### Can I use loc= values with XPath expressions?

Yes, prefix your locator with `xpath:` to use XPath syntax. For example: `await page.click('loc=xpath=//div[@class="modal"]//button')`. This is evaluated by the element resolver alongside other locator types.