# Add panorama tags — Dnalogel

Load a typed text hotspot, respond to clicks, and remove it during cleanup.

Canonical: https://developer.realsee.ai/docs/dnalogel/panorama-tags
Source: https://developer.realsee.ai/docs/dnalogel/panorama-tags.md
Language: en

[Download examples](https://developer.realsee.ai/starters/react-five/1.3.0/starter.zip)

Use a text hotspot when the visitor should discover a named point in a captured space. This example uses `PanoTagPlugin` from the [quickstart](https://developer.realsee.ai/docs/dnalogel/quickstart).

## Supply a position in the current scene

A tag's `position` is a three-number spatial coordinate, not a screen pixel. Obtain it from the current Work or your scene authoring workflow. Do not copy arbitrary coordinates from another scene and interpret an invisible result as a load failure.

The `Tag<'Text', '2DPoint'>` type fixes both the content schema and the attachment shape. Text content uses `title` and `description`; the older `text` property is deprecated.

```ts title="examples/sdk-guides/src/dnalogel/tags.ts"
import type { PanoTagPlugin, Tag } from '@realsee/dnalogel'

type TagsController = ReturnType<typeof PanoTagPlugin>

export async function addTextHotspot(tags: TagsController, position: [number, number, number]) {
  const tag: Tag<'Text', '2DPoint'> = {
    id: 'welcome', contentType: 'Text', stickType: '2DPoint', position,
    data: { title: 'Welcome', description: 'Explore this captured space.' }
  }
  await tags.load({ tagList: [tag] })
  tags.enable()
  await tags.show()
  const stop = tags.hooks.on('click', ({ tag: clicked }) => {
    if (clicked.id === 'welcome') tags.changeUnfoldedById('welcome', true)
  })
  return () => { stop(); tags.destroyTagById('welcome') }
}
```

Call the function with the ready controller and position, then retain the returned cleanup function. `load({ tagList })` replaces the controller's tag data. Use `addTag()` if you intend to append without replacing existing tags.

## Change or remove a hotspot

The controller exposes `changeDataById`, `changePositionById`, `changeEnabledById`, `changeUnfoldedById`, and `destroyTagById`. Retain stable IDs so updates target the intended tag. Tag clicks are subscribed through **`tags.hooks.on('click', ...)`**, not `tags.on(...)`.

The task's cleanup unsubscribes the click listener and removes its tag. The owner of the Five instance still calls the quickstart factory's `dispose()` on unmount.

## Verify

Confirm that the tag is visible from a suitable viewpoint, opens on click, and disappears after cleanup. Rotate away and back to check visibility. A successful load promise does not prove that your supplied coordinate lies inside the visible scene.

[Published controller](https://unpkg.com/@realsee/dnalogel@3.81.10/libs/PanoTagPlugin/controller/index.d.ts) · [Tag schema](https://unpkg.com/@realsee/dnalogel@3.81.10/libs/PanoTagPlugin/typings/tag/Tag.d.ts)
