# Archify Deep Linking: How to Use Focus, Route, and Lens Parameters to Share Precise Diagram States

> Master Archify deep linking with focus, route, and lens parameters. Share precise diagram states easily using URL hashes for static exports and embeds.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: how-to-guide
- Published: 2026-08-10

---

**Archify uses a declarative URL‑hash protocol (`#focus`, `#route`, `#lens`, `#view`) to encode diagram states so readers can restore exact views via simple links—no server required, works in static exports and embeds.**

The [tt-a1i/archify](https://github.com/tt-a1i/archify) viewer treats every selection as a **shareable address**. When you focus a node, trace a route, or apply a semantic lens, Archify updates `location.hash` using `history.replaceState`. This creates portable, bookmarkable URLs that survive static hosting, print-to-PDF, and iframe embeds. The implementation lives entirely in the frontend template at [`archify/assets/template.html`](https://github.com/tt-a1i/archify/blob/main/archify/assets/template.html), lines 7029–8063, with no backend dependencies.

## The Four Deep Linking Parameters

Archify recognizes four hash patterns. Each encodes a distinct "state lens" without autoplay or camera animation, making links deterministic and cache-friendly.

| Parameter | Syntax | Restored State |
|-----------|--------|----------------|
| **Focus** | `#focus=<node-id>` with optional `&reach=upstream\|downstream` | Highlights one node and its one-hop neighborhood |
| **Route** | `#route=<source-id>~<target-id>` | Displays the shortest authored path between two nodes |
| **Lens** | `#lens=<kind>~<kind>` | Filters to a semantic comparison between node kinds |
| **View** | `#view=<view-id>` | Recalls a saved camera position, zoom, and pan |

These hashes are **mutually exclusive**—only one active state per URL. The viewer parses `location.hash` on load and transitions directly to the encoded state.

## Focus: Highlight a Node and Its Context

The **focus** parameter centers a node and optionally reveals its upstream or downstream dependencies. This is the default state when users click any node in the diagram.

### Basic Focus Syntax

```

#focus=api-gateway

```

### Focus with Reachability Modifier

```

#focus=api-gateway&reach=upstream

```

The `reach` parameter accepts two values:

- **`upstream`** — Shows nodes that feed into the focused node
- **`downstream`** — Shows nodes that depend on the focused node

Omitting `reach` displays only the immediate neighbors in both directions.

### HTML Example: Focus Links

```html
<!-- Direct link to a single node -->
<a href="https://tt-a1i.github.io/archify/gallery/artifacts/web-app.architecture.html#focus=api-gateway">
  Focus on API Gateway
</a>

<!-- Include upstream dependencies -->
<a href="https://tt-a1i.github.io/archify/gallery/artifacts/web-app.architecture.html#focus=api-gateway&reach=upstream">
  Show API Gateway and its upstream
</a>

```

The hash generation logic in [`archify/assets/template.html`](https://github.com/tt-a1i/archify/blob/main/archify/assets/template.html) builds this string from internal state variables `activeIds` and `reachabilityMode`, then commits it via `history.replaceState` to keep the browser address bar synchronized without adding history entries.

## Route: Display Shortest Paths Between Nodes

The **route** parameter computes and displays the deterministic shortest authored path from a source node to a target node. This is not an autoplay animation—it is a static overlay of the computed path.

### Route Syntax

```

#route=<source-id>~<target-id>

```

The tilde (`~`) separates source and target. Both IDs must match the `id` fields in your architecture definition.

### HTML Example: Route Link

```html
<a href="https://tt-a1i.github.io/archify/gallery/artifacts/cache-miss.sequence.html#route=web~db">
  Show route from Web App → Postgres
</a>

```

Route hashes are validated by `archify/test/route-probe.test.mjs` at line 71, confirming the `~` delimiter and ID encoding behavior.

## Lens: Filter by Semantic Node Kinds

The **lens** parameter activates Archify's **Semantic Lens** UI (keyboard shortcut `L`) and filters the diagram to show only relationships between specified node kinds. This enables architectural comparisons—backend versus database layers, service versus client boundaries, etc.

### Lens Syntax

```

#lens=<kind-1>~<kind-2>

```

Both kinds must be defined in your architecture's `nodes[*].kind` metadata. The lens displays:

1. All nodes of `kind-1` and `kind-2`
2. Direct authored edges between nodes of these kinds
3. Nodes of other kinds that bridge connections (if no direct edge exists)

### HTML Example: Lens Link

```html
<a href="https://tt-a1i.github.io/archify/gallery/artifacts/production-deployment.architecture.html#lens=backend~database">
  Compare backend vs database roles
</a>

```

The lens hash specification is documented in [`docs/research-visual-evolution-round-35.md`](https://github.com/tt-a1i/archify/blob/main/docs/research-visual-evolution-round-35.md), lines 58–86, with test coverage confirming panel population and edge filtering logic.

## View: Restore Saved Camera States

The **view** parameter recalls pre-saved camera configurations—pan, zoom, and rotation—without changing node selection or filters.

### View Syntax

```

#view=<view-id>

```

View IDs are generated when users manually save a camera position via the UI or programmatically via the Archify API.

## Programmatic Hash Construction

For custom integrations, build hashes using this pattern derived from the template implementation:

```javascript
function makeHash({type, a, b, extra}) {
  switch (type) {
    case 'focus':
      // a = node-id, b = reach (optional), extra unused
      return `#focus=${encodeURIComponent(a)}${b ? `&reach=${b}` : ''}`;
    
    case 'route':
      // a = source-id, b = target-id
      return `#route=${encodeURIComponent(a)}~${encodeURIComponent(b)}`;
    
    case 'lens':
      // a = kind-1, b = kind-2
      return `#lens=${encodeURIComponent(a)}~${encodeURIComponent(b)}`;
    
    case 'view':
      // a = view-id
      return `#view=${encodeURIComponent(a)}`;
    
    default:
      throw new Error(`Unknown hash type: ${type}`);
  }
}

// Usage examples
makeHash({type: 'focus', a: 'api-gateway'});
// → "#focus=api-gateway"

makeHash({type: 'focus', a: 'api-gateway', b: 'upstream'});
// → "#focus=api-gateway&reach=upstream"

makeHash({type: 'route', a: 'web', b: 'db'});
// → "#route=web~db"

makeHash({type: 'lens', a: 'backend', b: 'database'});
// → "#lens=backend~database"

```

Always URI-encode node IDs and kind names to handle spaces, special characters, and Unicode safely.

## Static Export and Embed Compatibility

Because Archify deep linking relies solely on `location.hash` parsing, these URLs work identically across:

- **Static HTML exports** — GitHub Pages, Netlify, S3
- **Print contexts** — hash persists in PDF links if the reader supports it
- **Iframe embeds** — parent page can manipulate child hash to control view
- **Email and chat** — links open directly to specified state

No server-side routing, no session storage, no cookies. The hash is parsed once on `DOMContentLoaded` and applied immediately.

## Where Deep Linking Is Implemented

| File | Purpose | Relevant Lines |
|------|---------|--------------|
| [`archify/assets/template.html`](https://github.com/tt-a1i/archify/blob/main/archify/assets/template.html) | Hash generation via `history.replaceState` and parsing on load | 7029–8063 |
| [`README.md`](https://github.com/tt-a1i/archify/blob/main/README.md) | Stable-link format documentation and example URLs | 252 |
| `archify/test/semantic-passport.test.mjs` | Unit test for `#focus` hash generation | 74 |
| `archify/test/route-probe.test.mjs` | Unit test for `#route` hash format | 71 |
| [`docs/research-visual-evolution-round-35.md`](https://github.com/tt-a1i/archify/blob/main/docs/research-visual-evolution-round-35.md) | Lens hash specification | 58–86 |
| [`docs/research-visual-evolution-round-33.md`](https://github.com/tt-a1i/archify/blob/main/docs/research-visual-evolution-round-33.md) | Focus hash behavior | 76–77 |

## Summary

- **Four parameters** control Archify deep linking: `#focus`, `#route`, `#lens`, and `#view`
- **Focus** highlights single nodes with optional upstream/downstream context
- **Route** displays static shortest-path overlays between two nodes
- **Lens** filters diagrams to semantic kind comparisons, activated via `L` shortcut
- **Declarative hashes** work in static exports, prints, and embeds without runtime dependencies
- **Implementation** resides in [`archify/assets/template.html`](https://github.com/tt-a1i/archify/blob/main/archify/assets/template.html) with full test coverage

## Frequently Asked Questions

### What happens if I combine multiple parameters in one URL?

Archify parses only the first recognized parameter. If you provide `#focus=api-gateway&route=web~db`, the viewer applies the focus state and ignores the route. Construct separate links for distinct states.

### Do deep links work with password-protected or private diagrams?

Yes. The hash is client-side only—no authentication tokens travel in the URL. Access control depends entirely on your hosting layer (HTTP basic auth, Netlify Identity, etc.). The hash functions identically once the page loads.

### Can I trigger deep linking programmatically from outside the iframe?

Yes. For embedded Archify diagrams, the parent page can update `iframe.src` with a new hash, or use `iframe.contentWindow.location.hash = '#focus=new-node'` if same-origin. The viewer detects hash changes via `window.onhashchange` and transitions accordingly.

### Why does my focus link show different neighbors than expected?

The `reach` parameter strictly controls hop direction, but the visible neighborhood also depends on the **authored edges** in your architecture file. If no upstream dependency is declared for a node, `reach=upstream` will appear empty. Verify your [`.architecture.yml`](https://github.com/tt-a1i/archify/blob/main/.architecture.yml) or [`.sequence.yml`](https://github.com/tt-a1i/archify/blob/main/.sequence.yml) edge definitions.