# How Guided Views Work in the Archify Viewer: Architecture and Implementation

> Discover how Archify viewer uses a client-side state machine and JSON-defined camera shots for guided views. Navigate architectural stories step-by-step effortlessly.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: internals
- Published: 2026-08-14

---

**Guided views in the Archify viewer are implemented as a client-side state machine that renders a toolbar from JSON-defined camera shots, enabling step-by-step navigation through architectural stories without requiring server calls.**

The **tt-a1i/archify** repository provides a lightweight 3D document viewer where guided views serve as the primary mechanism for authors to create interactive, cinematic walkthroughs. Understanding how guided views work reveals a purely client-side architecture that leverages HTML data attributes and minimal JavaScript to manage complex playback states across four key source files.

## Architecture Overview

The implementation follows a three-layer architecture spanning markup, presentation, and behavior.

### HTML Markup Layer

In [`scripts/mco-runtime.html`](https://github.com/tt-a1i/archify/blob/main/scripts/mco-runtime.html), the system renders a container with the class `guided-views` that holds the entire interface. Each individual view is represented as a `<div class="guided-view-copy">` containing visible labels and notes, paired with a hidden `<button class="guided-view-stop">` that stores the view's serialized state and camera position.

### CSS Styling Layer

The stylesheet in [`scripts/mco-runtime.html`](https://github.com/tt-a1i/archify/blob/main/scripts/mco-runtime.html) defines the `.guided-views` class and its child selectors (`.guided-view-play`, `.guided-view-stop`, `.guided-view-copy`). These rules render the toolbar interface when the document runs standalone, but apply `display:none !important` when `data-embed="true"` or `data-motion="still"` attributes are present on the container.

### JavaScript Logic Layer

File `scripts/build-gallery.mjs` coordinates the runtime behavior. The script sets a boolean flag `guidedPlayback` to `true` whenever a document contains a non-zero `viewCount`, triggering the initialization of navigation controls. The logic maintains a state machine where each view button carries a `data-story-beat-state` attribute cycling through `pending`, `next`, `past`, and `active` values to drive UI updates and camera transitions.

## The Build Pipeline and Data Generation

The process begins with a JSON description of camera states and compiles into interactive HTML.

1. **Authoring**: Creators define view objects with properties like `label`, `note`, and `cameraState`.
2. **Compilation**: `scripts/build-gallery.mjs` parses this JSON and emits the `<div class="guided-views">` block, injecting hidden buttons for each view and calculating the `guidedPlayback` flag.
3. **Attribute Injection**: The build step adds data attributes including `data-preset`, `data-present`, `data-document-hidden`, and `data-story-beat` to control visibility and initial state.

## Navigation and State Machine

User interaction is handled through a declarative state system rather than imperative DOM manipulation.

The viewer tracks playback position using the `data-story-beat-state` attribute on each `.guided-view-stop` button. When users click the **Prev** or **Next** buttons, the JavaScript advances the cursor, updates the container's `data-story-beat` attribute, and triggers camera transitions through the Archify API. The **Play** button toggles `data-playing="true"` on the container, initiating automatic stepping through views at fixed intervals while updating button opacity and icons based on the current state.

## Embedding and Contextual Visibility

The toolbar automatically adapts to its presentation context. When the containing element specifies `data-embed="true"`, CSS rules hide the entire `.guided-views` interface, allowing the viewer to integrate seamlessly into external pages while preserving the underlying navigation logic for programmatic control.

## Exporting and Deep Linking

Each guided view supports one-click sharing through the copy functionality. The event handler in `scripts/build-gallery.mjs` constructs a deep link by appending the current view ID to `location.href`, then writes the result to the system clipboard using `navigator.clipboard.writeText()`.

## Implementation Examples

*Basic Toolbar Markup*

```html
<div class="guided-views" data-preset="blueprint">
  <button id="guided-view-prev" disabled>←</button>
  <button id="guided-view-play" aria-pressed="false">▶︎</button>
  <button id="guided-view-next">→</button>

  <div class="guided-view-copy">
    <strong id="guided-view-label">Intro</strong>
    <small id="guided-view-note">Overview of the architecture</small>
  </div>

  <button class="guided-view-stop" data-story-beat-state="pending"></button>
</div>

```

*Playback Initialization*

```javascript
// From scripts/build-gallery.mjs
if (entry.viewCount > 0) {
  guidedPlayback = true;  // Enables toolbar rendering
}

// Navigation handler
document.getElementById('guided-view-next')
  .addEventListener('click', () => advanceView());

function advanceView() {
  const container = document.querySelector('.guided-views');
  const next = container.querySelector('[data-story-beat-state="next"]');
  if (!next) return;
  
  setCameraFromView(next.dataset.viewId);
  next.dataset.storyBeatState = 'active';
}

```

*Copy to Clipboard*

```javascript
document.querySelector('.guided-view-copy button')
  .addEventListener('click', async () => {
    const link = location.href + `#view=${currentViewId}`;
    await navigator.clipboard.writeText(link);
  });

```

## Key Source Files

- `scripts/build-gallery.mjs`: Generates markup, manages `guidedPlayback` state, and wires navigation handlers.
- [`scripts/mco-runtime.html`](https://github.com/tt-a1i/archify/blob/main/scripts/mco-runtime.html): Demonstrates the live toolbar implementation and contains the CSS styling block.
- [`scripts/guide-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/guide-template.html): Template used during builds to produce pages with guided-view support.
- [`scripts/start-template.html`](https://github.com/tt-a1i/archify/blob/main/scripts/start-template.html): Base viewer template including responsive CSS rules for toolbar visibility.

## Summary

- Guided views are defined in JSON and compiled into HTML by `scripts/build-gallery.mjs`.
- The `guidedPlayback` flag activates the feature only when views exist.
- State management relies on `data-story-beat-state` attributes cycling through `pending`, `next`, `past`, and `active`.
- The toolbar hides automatically via CSS when `data-embed="true"` is set.
- All functionality executes client-side with no server dependencies after the initial page load.

## Frequently Asked Questions

### What triggers the guided views toolbar to appear?

The toolbar renders when `scripts/build-gallery.mjs` detects a non-zero `viewCount` in the document configuration and sets `guidedPlayback` to `true`. This flag initializes the DOM listeners and unhides the `.guided-views` container.

### How does the state machine track which view is active?

Each view button stores its status in the `data-story-beat-state` attribute, which can hold values of `pending`, `next`, `past`, or `active`. The JavaScript updates these values and the container's `data-story-beat` attribute to synchronize the camera position with the UI highlight.

### Can I use guided views when embedding the Archify viewer in another site?

Yes, but the toolbar hides automatically. When the root element carries `data-embed="true"`, CSS rules apply `display:none !important` to the `.guided-views` class. The underlying navigation logic remains available for programmatic control via the Archify API.

### Which source files should I modify to customize the guided views styling?

Edit [`scripts/mco-runtime.html`](https://github.com/tt-a1i/archify/blob/main/scripts/mco-runtime.html) to change the CSS rules for `.guided-views` and its children. For structural changes to how views are generated, modify `scripts/build-gallery.mjs`, which controls the HTML emission and state initialization.