# How the Share Link Functionality Works in Gods Eye View: A Technical Deep Dive

> Explore the technical details of Gods Eye View share link functionality. Learn how viewer state is encoded in the URL hash and restored using JavaScript.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: deep-dive
- Published: 2026-09-12

---

**Gods Eye View encodes the full viewer state—including camera position, visual style, UI panel layout, and detection settings—into the URL hash, enabling deterministic restoration via [`src/sharelink.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js) using `parseInitialHash()`, `applyState()`, and debounced `_scheduleUpdate()` methods.**

The **share link functionality** in the [bilawalsidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view) repository provides a deterministic state serialization system that compresses complex 3D visualization configurations into portable URLs. This implementation allows users to share exact camera perspectives, visual presets, and interface arrangements through a compact hash-based encoding scheme. The architecture centers on the `ShareLinkManager` class, which orchestrates bidirectional synchronization between the application state and the browser's URL fragment.

## The Four-Stage Share Link Pipeline

The share link functionality operates through a coordinated four-stage pipeline within [`src/sharelink.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js), handling everything from initial page load restoration to real-time URL updates during user interaction.

### Stage 1: Parsing the Incoming Hash

When the application initializes, **`ShareLinkManager.parseInitialHash()`** reads `window.location.hash` and constructs a validated state object. This method uses `URLSearchParams` to extract camera coordinates (latitude, longitude, altitude), visual style tokens, bloom/sharpen flags, detection settings, scope-mask parameters, map stack configurations, layer states, and panel layouts.

The parser validates numeric ranges and converts URL-safe tokens back to internal representations. For example, style tokens like `crt`, `nvg`, and `flir` map to internal styles (`retro`, `surveillance`, `thermal`) via the `STYLE_TO_URL` registry. See the implementation in lines [55-84](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L55-L84) and the detailed decoding logic in lines [72-100](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L72-L100).

### Stage 2: Applying the Restored State

Once parsed, **`ShareLinkManager.applyState(state, ...)`** converts geographic coordinates into Cesium Cartesian destinations and constructs camera orientations. The method optionally triggers animated transitions using `viewer.camera.flyTo` while forwarding visual preset data to the `onRestore` callback.

This callback distributes state fragments—style configurations, bloom intensity, HUD visibility, detection modes, and scope parameters—to the respective application subsystems. The camera flight handling and state application logic resides in lines [49-91](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L49-L91), with specific flight controls in lines [61-90](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L61-L90).

### Stage 3: Synchronizing Runtime Changes

During active usage, the manager maintains URL currency through **`_scheduleUpdate()`**, which debounces calls to **`_updateHash()`** using a 150ms timeout. The **`_buildHashParams()`** method assembles a deterministic `URLSearchParams` object that mirrors the parser's expected format, writing updates via `history.replaceState` to avoid cluttering browser history.

This process captures camera movements (registered via `camera.changed` listeners), UI panel state changes, style selections, and layer switches. The hash-building algorithm appears in lines [74-98](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L74-L98) with the debounced update flow at lines [60-66](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L60-L66).

### Stage 4: Generating Copy-to-Clipboard Links

When users request a shareable link, **`copyLink()`** invokes `_buildHashParams()` and appends a fresh **`at`** timestamp parameter (`SHARE_CREATED_AT_PARAM`) before writing the complete URL to the clipboard via `navigator.clipboard.writeText`. This timestamp enables the UI to display relative creation times ("link created 5 minutes ago") while being stripped during normal navigation to prevent URL aging. Implementation details are in lines [45-55](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L45-L55).

## Encoding Schemes and Parameter Compression

The share link functionality minimizes URL length through aggressive tokenization and whitelist-based parameter serialization.

### Visual Style Tokenization

Internal style names undergo compression through the **`STYLE_TO_URL`** mapping (lines [20-30](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L20-L30)):

- `normal` → `normal`
- `retro` → `crt`
- `surveillance` → `nvg`
- `thermal` → `flir`
- `anime` → `anim`
- `noir` → `noir`
- `snow` → `snow`

### Style-Specific Parameter Registry

Each visual style defines valid numeric parameters through **`SHARE_STYLE_PARAM_REGISTRY`**, which specifies allowed tokens, scaling factors, and min/max ranges. The **`encodeStyleParamState()`** method writes these as compact `<token>.<scaled>` pairs, while **`decodeStyleParamState()`** reverses the transformation using the registry metadata. See the encoding logic in lines [55-75](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L55-L75) and decoding in lines [60-74](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L60-L74).

### Panel State Serialization

UI panel configurations serialize via **`_encodePanelStateParam()`** using a compact dot-notation format:

```

<panelToken>.c.<0|1>_<panelToken>.p.<0|1>

```

Where `.c.` indicates collapsed state and `.p.` indicates pinned status. The **`decodePanelStateParams`** function reconstructs panel specifications from these tokens (lines [86-101](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L86-L101) and [95-116](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L95-L116)).

### Layer and Scope Configuration

Layer state serialization delegates to **`encodeLayerStateParams`** imported from [`src/data/layerState.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/layerState.js), handling terrain and imagery stack configurations. Scope-mask parameters use dedicated short tokens:

- `scf` → `scopeFeatherPct`
- `sce` → `scopeTerminusPct`
- `dm` → detection mode
- `dd` → detection density
- `da` → detection allocation
- `kf` / `ko` → kill flash / overlay settings
- `cr` → celestial ring toggle

These parse in lines [96-108](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L96-L108).

## Lifecycle and Integration Patterns

The `ShareLinkManager` follows a strict lifecycle to prevent state corruption during restoration:

1. **Construction**: Instantiation registers a `camera.changed` listener that triggers `_scheduleUpdate` for position tracking
2. **Initial Restoration**: `parseInitialHash()` runs on load; if valid state exists, `applyState()` executes while suppressing hash updates (`_initialRestorePending` flag) until `completeInitialRestore()` finalizes the process
3. **Runtime Synchronization**: UI components call setter methods (`onStyleChange`, `onToggleChange`, `onPanelStateChange`) which flag the manager dirty and schedule debounced hash writes
4. **Destruction**: The `destroy()` method aborts pending camera flights, removes event listeners, and disables further hash modifications

## Implementation Examples

Initialize the manager and restore state on application startup:

```javascript
import { ShareLinkManager } from './sharelink.js';

const manager = new ShareLinkManager(viewer, {
  onRestore: (visualState) => {
    styleManager.applyVisualState(visualState);
  },
  isNavigationCurrent: (token) => navigationToken === token,
  cancelOwnedNavigation: () => viewer.camera.cancelFlight(),
});

const initialState = manager.parseInitialHash();
if (initialState) {
  manager.applyState(initialState, { navigationToken: Symbol('share') })
    .then(() => manager.completeInitialRestore());
}

```

Automatically synchronize UI changes to the URL:

```javascript
// Style change triggers hash update via manager.onStyleChange()
styleManager.setStyle('surveillance');

```

Generate a shareable link with creation timestamp:

```javascript
async function copyCurrentLink() {
  const ok = await manager.copyLink();
  console.log(ok ? 'Link copied with fresh timestamp' : 'Clipboard write failed');
}

```

Debug parse state manually:

```javascript
const params = new URLSearchParams('#lat=37.77&lon=-122.42&alt=800&style=nvg&bloom=1');
const state = manager.parseInitialHash();
console.log(state); // Full camera, style, and UI configuration object

```

## Summary

- **State serialization** occurs entirely client-side in [`src/sharelink.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js), encoding camera coordinates, visual presets, UI panels, and detection settings into URL hash parameters
- **Four-stage pipeline** handles parsing (`parseInitialHash`), restoration (`applyState`), runtime synchronization (`_scheduleUpdate`), and clipboard generation (`copyLink`)
- **Token compression** maps verbose internal names to short URL tokens (e.g., `surveillance` → `nvg`) and uses scaled integer encoding for numeric parameters
- **Debounced updates** write hash changes via `history.replaceState` 150ms after state changes cease, preventing URL flicker during rapid interactions
- **Lifecycle guards** prevent restoration loops by suppressing hash writes during initial state application via the `_initialRestorePending` semaphore

## Frequently Asked Questions

### What parameters are included in a Gods Eye View share link?

Share links include camera position (latitude, longitude, altitude), visual style tokens, bloom/sharpen flags, HUD visibility, detection mode settings, scope-mask feather and terminus percentages, UI panel collapsed/pinned states, layer stack configuration, and optional creation timestamps. All parameters serialize through [`src/sharelink.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js) using compact token abbreviations to minimize URL length.

### How does the application prevent share links from becoming stale during navigation?

The `copyLink()` method adds a temporary `at` (created-at) timestamp parameter (`SHARE_CREATED_AT_PARAM`) specifically for clipboard operations, which the UI uses to display relative age indicators. During normal navigation and camera movement, the `_updateHash()` method writes the current state without this timestamp, ensuring the live URL never contains stale temporal data.

### Can share links restore exact camera orientations and angles?

Yes, the `applyState()` method converts parsed latitude/longitude/altitude values into Cesium Cartesian coordinates and reconstructs the full camera orientation including heading, pitch, and roll. The restoration optionally uses `viewer.camera.flyTo` for smooth animated transitions or instantaneous positioning depending on the navigation context provided during the `applyState()` call.

### What happens if a share link contains invalid or out-of-range parameters?

The `parseInitialHash()` method implements validation guards that clamp numeric values to defined min/max ranges specified in `SHARE_STYLE_PARAM_REGISTRY` and filter unknown parameters. Invalid tokens fall back to defaults, ensuring the application loads safely even with malformed or partial hash data, though specific invalid parameters are silently dropped during the parsing phase (lines [72-100](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/sharelink.js#L72-L100)).