Archify Deep Linking: How to Use Focus, Route, and Lens Parameters to Share Precise Diagram States
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 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, 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 nodedownstream— Shows nodes that depend on the focused node
Omitting reach displays only the immediate neighbors in both directions.
HTML Example: Focus Links
<!-- 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 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
<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:
- All nodes of
kind-1andkind-2 - Direct authored edges between nodes of these kinds
- Nodes of other kinds that bridge connections (if no direct edge exists)
HTML Example: Lens Link
<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, 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:
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 |
Hash generation via history.replaceState and parsing on load |
7029–8063 |
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 |
Lens hash specification | 58–86 |
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
Lshortcut - Declarative hashes work in static exports, prints, and embeds without runtime dependencies
- Implementation resides in
archify/assets/template.htmlwith 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 or .sequence.yml edge definitions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →