sixty

agente de cliente

Browser

Lo que el servidor no puede ver: cuánto tardó de verdad la página para una persona real, qué clics no hicieron nada, y qué componente se volvió a renderizar cuatrocientas veces.

paquete
@sixty-sh/browser en npm
funciona sobre
Cualquier página. Alrededor de 2,4 µs de coste bloqueante por cada petición que observa.
código
sixty-sh/sixty-browser

Cómo instalarlo

Next, Remix, SvelteKit and friends. The key stays server-side behind a proxy route.

La instalación está escrita como un prompt para el agente de código que ya tienes abierto, no como una lista de tareas para ti. Es deliberado: nombra lo que tiene que ser cierto cuando la instalación esté terminada en vez de qué archivos editar, porque dónde va el código depende del framework y ponerlo en el sitio equivocado falla en silencio. Un agente puede leer tu repositorio y deducirlo; un párrafo en una página de documentación no.

El mismo texto es lo que devuelve install_sixty a través de el servidor MCP y lo que el colector sirve en /v1/setup?kind=browser. Hay una sola copia.

la instalación de Browser, completa
Set up @sixty-sh/browser in this project so page performance reports to sixty.

Before editing, ask the user: "Do you want privacy-masked session replay?"
Do not choose for them. If yes, use the replay-enabled init in step 3. If no,
use plain init() and do not add replay configuration.

1. Install @sixty-sh/browser.

2. Add a server-side endpoint at the path /api/drift whose GET and POST
   handlers are both the same createSixtyProxy() handler from
   "@sixty-sh/browser/proxy". Work out the correct
   file and export style for this project's framework and router. It must run
   on the server, not the client. POST receives measurements and recordings;
   GET reads the Sessions policy. Omitting either method is an incomplete install.

3. Call init() from "@sixty-sh/browser" exactly once in the browser, in a
   client component that is mounted on every page (the root layout is usually
   right). If the user chose replay, call
   init({ replay: { enabled: true } }); otherwise call init(). The default
   endpoint is /api/drift.
   @sixty-sh/browser owns the compatible recorder dependency, so do not install
   or import rrweb separately. Replay remains privacy-masked and the Sessions
   setting decides whether recordings are off, incident-only, or sampled.

4. Set these server-side environment variables (never client-exposed ones):
      SIXTY_API_KEY   = a secret key starting sixty_sk_ — ask me for it, I can
                        generate one on the Settings page. Do not invent one.
      SIXTY_SERVICE   = my-app
      SIXTY_ENDPOINT  = https://ingest.sixty.sh

5. If this project has a router that knows its route patterns, call setRoute()
   from "@sixty-sh/browser" with the pattern (e.g. "/orders/[id]") on each
   navigation. Without it, routes are guessed from the URL, which is close but
   not exact.

Constraints — these are correctness requirements, not style preferences:
- SIXTY_API_KEY must never reach the browser. Do not prefix it with NEXT_PUBLIC_,
  VITE_, or PUBLIC_, do not pass it to init(), and do not import it into any
  client component. The whole point of the proxy is that the key stays server-side.
- Do not add any analytics, user id, session id, or cookie. The agent is
  deliberately anonymous and must stay that way.
- Do not call init() during server rendering. It returns null there, so guard it
  in an effect or a client-only component rather than at module scope.

When you are done, tell me which files you changed and how to deploy so I can
confirm data is arriving.

Necesita una clave secreta — empieza por sixty_sk_ y se queda en el servidor. Genera una en la página de Ajustes cuando hayas iniciado sesión.

Qué mide

señalunidadqué significa
web_vitalmsa page-speed metric got worse for real users
render_stormrendersa component re-renders many times for one interaction
dead_interactionof clicksusers click this and nothing observable happens
stuck_loadingof loads never finisha loading state is entered and never left
client_errorof viewsthis error is being thrown in real users’ browsers
auth_failures—The server is turning these away on permission grounds rather than failing. People see an empty page or a save that quietly does nothing.
silent_empty—The query runs and succeeds, and returns no rows where it used to return plenty. Nothing reports an error, so the page just renders blank — this is what a broken permission rule looks like from the outside.
latencyms per callthis operation takes longer end to end than it used to
errorserror ratea larger fraction of calls are throwing
runawaycalls per minutethis operation is being called far more often than anything triggers it

Dónde se engancha

  • Next, Remix, SvelteKit — Tener servidor propio significa que la clave se queda en el servidor detrás de una ruta de proxy — coge este nivel, no el de Lovable.
  • Sin servidor alguno — Lovable, un hosting estático, una aplicación solo con Supabase: mira el nivel de Lovable, que usa una clave pública anclada al origen.

Qué hace solo este

  • Velocidad de página por ruta y por país — LCP, INP, CLS y TTFB de visitas reales, comparados con la versión anterior y no con una ejecución de laboratorio.
  • Bucles de render — Una interacción que vuelve a renderizar la página cientos de veces. Nada del lado servidor puede ver esto y no se lanza ningún error.
  • Clics que no hacen nada — Un control que se pulsa y no produce ningún cambio medible — ni petición, ni navegación, ni mutación del DOM.
  • Cargas que nunca terminan — Un estado de carga en el que se entra y del que no se sale nunca, que es el fallo que produce un ticket de soporte y ninguna línea de registro.

Qué no puede hacer

  • No se recoge identidad de usuario de ningún tipo — sin id, sin sesión, sin cookie. Eso es una restricción de diseño y no un ajuste, así que «qué usuario vio esto» es una pregunta que este producto no puede responderle a nadie, nosotros incluidos.
  • Los frames de la pila en producción apuntan a chunks empaquetados. El nombre de la operación y el mensaje son lo que identifica un error de navegador, no el número de línea.

Configuración

Todos los agentes leen las mismas cuatro variables, y DRIFT_* sigue respondiendo allí donde lo hace SIXTY_* — el producto se renombró y ese nombre no es nuestro para retirarlo de los despliegues de otra gente.

SIXTY_API_KEYSin ella el agente se queda inerte y lo dice. Nunca adivina, nunca reintenta contra un endpoint desconocido, y nunca lanza una excepción.
SIXTY_SERVICECómo llamar a este servicio. Por defecto, el nombre del proyecto donde sea legible.
SIXTY_RELEASELa que más importa. Se recoge automáticamente en Vercel, Render, Railway, Fly, Heroku y GitHub Actions; en cualquier otro sitio, ponla al SHA del commit. Sin ella cada medición cae en un único cubo sin nombre y no se puede hacer ninguna comparación.
SIXTY_ENDPOINTDónde reportar. Por defecto http://localhost:4319, que es correcto en un portátil y erróneo en cuanto la aplicación se sirve a alguien más.

El resto — intervalo de envío, tasa de muestreo, qué instrumentar — está en el propio README del paquete, que es donde puede seguir siendo cierto según cambia el agente.

El agente Browser de sixty — qué mide y cómo se instala