# React SPA install

> React SPA guidance for installing the v1 widget once and updating context on router changes.

## Agent-ready snippet

```
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function loadAnswerlattice(widgetKey, updateContext) {
  const existing = document.querySelector('script[data-answerlattice-widget="v1"]');
  if (existing) {
    if (window.AnswerlatticeWidget) updateContext();
    else existing.addEventListener('load', updateContext, { once: true });
    return () => existing.removeEventListener('load', updateContext);
  }
  const script = document.createElement('script');
  script.src = 'https://answerlattice.com/widget/v1/answerlattice-widget.js';
  script.async = true;
  script.setAttribute('data-answerlattice-widget', 'v1');
  script.setAttribute('data-answerlattice-key', widgetKey);
  script.addEventListener('load', updateContext, { once: true });
  document.head.appendChild(script);
  return () => script.removeEventListener('load', updateContext);
}

export function AnswerlatticeInstall() {
  const location = useLocation();
  const widgetKey = import.meta.env.VITE_ANSWERLATTICE_WIDGET_KEY;

  useEffect(() => {
    if (!widgetKey) return;
    const updateContext = () => window.AnswerlatticeWidget?.page({
      path: location.pathname,
      title: document.title,
      feature: location.pathname.split('/').filter(Boolean)[0] || 'app',
      role: 'member',
      locale: navigator.language || 'en',
    });
    const removeLoadListener = loadAnswerlattice(widgetKey, updateContext);
    updateContext();
    return removeLoadListener;
  }, [location.pathname, widgetKey]);

  return null;
}
```

## Public API note

The public API may be account-gated. For most clients, install the AnswerLattice widget first.