Añadir Kaleidr Chat a un mapa de Mapbox
Al terminar esta guía tendrás una página con un mapa Mapbox GL JS y un panel de chat acoplado. Cuando un visitante hace una pregunta, la respuesta aparece progresivamente, sus lugares se muestran como marcadores en el mapa y la cámara se mueve para encuadrarlos. Funciona en todos los planes, incluido Free, con una clave publicable. Las preguntas consumen créditos de IA de tu organización.
Antes de empezar
- Una clave publicable de Kaleidr (
kld_pk_live_…) en kaleidr.com/api-keys. Las claves nuevas incluyen el permisoainecesario para Chat. Consulta Obtener una clave API. - El origen de tu página en los orígenes permitidos de la clave, si hay restricciones. Para desarrollo local añade, por ejemplo,
http://localhost:8080. - Un token de acceso de Mapbox (
pk.…) de tu cuenta Mapbox. Mapbox cobra el mapa; Kaleidr cobra las preguntas. Son independientes. - Mapbox GL JS cargado mediante un script, de modo que exista
window.mapboxgl. Si importas Mapbox desde npm, consulta Exponer una biblioteca importada con npm como global. - Un servidor HTTP como
npx serveopython -m http.server 8080. Abrir el archivo desde el disco no funciona. - Si tienes una Política de seguridad de contenido, autoriza los hosts descritos en Política de seguridad de contenido.
Paso 1: Disponer el mapa y la capa de chat
Coloca el mapa y el destino de montaje del chat dentro de un mismo contenedor posicionado. La capa de chat se superpone al mapa y deja pasar los eventos de puntero.
<div id="mapHost" style="position:relative; height:520px">
<div id="map" style="position:absolute; inset:0; z-index:0"></div>
<div id="chat" style="position:absolute; inset:0; z-index:1; pointer-events:none"></div>
</div>
Resultado esperado: nada todavía; únicamente un bloque vacío de 520 px. Temas y disposición explica cada declaración.
Paso 2: Cargar Mapbox GL JS y crear el mapa
Carga la hoja de estilos en el encabezado de la página y el script antes de tu código. La hoja de estilos es obligatoria: sin ella, el mapa no se representa correctamente.
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.css" />
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.js"></script>
<script>
mapboxgl.accessToken = 'pk.…';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-0.12, 51.5],
zoom: 11,
});
</script>
Resultado esperado: un mapa Mapbox del centro de Londres que se puede arrastrar y ampliar.
Paso 3: Cargar kaleidr.js
Añade el loader después del script de Mapbox y antes del código que monta el panel.
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
Resultado esperado: la página no cambia. En la consola, Kaleidr.version devuelve una cadena de versión.
Paso 4: Montar el panel de chat
Indica tu clave y el objeto de mapa activo.
const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
No hace falta esperar al evento load del mapa. Kaleidr.mount devuelve el control inmediatamente; el panel aparece cuando se carga el bundle de chat y la clave se intercambia por una sesión.
Resultado esperado: una barra de entrada «Ask Kaleidr» en la esquina superior izquierda del mapa.
La página completa
Guarda el archivo como index.html, sustituye las dos claves y sirve la carpeta por HTTP.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Kaleidr Chat on Mapbox</title>
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.css" />
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
#mapHost { position: relative; height: 100vh; }
#map { position: absolute; inset: 0; z-index: 0; }
#chat { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
</style>
</head>
<body>
<div id="mapHost">
<div id="map"></div>
<div id="chat"></div>
</div>
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.4/mapbox-gl.js"></script>
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<script>
mapboxgl.accessToken = 'pk.…';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-0.12, 51.5],
zoom: 11,
});
const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
</script>
</body>
</html>
Cómo funciona
| El visitante | El panel | Tu mapa Mapbox |
|---|---|---|
| Envía una pregunta | Se abre una ventana de chat y el texto de la respuesta llega progresivamente. | Todavía no ocurre nada. |
| Espera | Muestra una tarjeta por cada lugar de la respuesta. | Aparece un marcador por lugar a medida que se localiza. Para uno, la cámara vuela hacia él; para varios, los encuadra con un margen que evita el panel. |
| Hace clic en un marcador o resultado | Abre una ficha con resumen, fotos y una herramienta de rutas. | Al hacer clic en un resultado, la cámara se centra en ese lugar. |
| Solicita indicaciones | Muestra la distancia y duración de la ruta. | Se dibuja y encuadra una línea de ruta. |
| Hace otra pregunta | Añade el mensaje a la misma conversación. | Se agregan marcadores y permanecen los anteriores. |
| Cierra el chat | Vuelve a la barra de entrada y termina la conversación. | Se eliminan marcadores y ruta. |
Detalles específicos de Mapbox GL JS:
- Los marcadores son objetos
Markerde Mapbox con un elemento HTML y no interfieren con los tuyos. - La ruta se dibuja mediante fuentes y capas añadidas por el panel a tu estilo, que se retiran después. Tus propias fuentes y capas no se modifican.
- La sesión se renueva automáticamente mientras el panel esté montado. No necesitas gestionar tokens.
Comprobar que funciona
En la página
- La barra Ask Kaleidr aparece sobre la esquina superior izquierda del mapa.
- Escribe
Show me three museums in Londony pulsa Enter. Aparece texto progresivamente, se añaden tres marcadores y el mapa se ajusta para mostrarlos.
En la consola
- Ningún error ni advertencia contiene
[kaleidr.
En la pestaña Network
| Solicitud | Resultado esperado |
|---|---|
GET https://cdn.kaleidr.com/embed/v1/kaleidr.js | 200 |
GET https://cdn.kaleidr.com/embed/v1/chat.js | 200 |
POST https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions | 200, con cuerpo JSON como el ejemplo siguiente |
POST https://api.kaleidr.com/inference-api/b2b/v1/chat/control/stream (después de preguntar) | 200, content-type: text/event-stream |
{ "session_token": "kld_sess_live_…", "expires_in": 900, "product": "chat" }
Si no funciona
El SDK escribe un mensaje breve y no repite el motivo del servidor. Si falla una solicitud, ábrela en Network y lee su respuesta JSON. En un 403 o 404 el código aparece en detail; en un 429, en error, acompañado de una frase en detail.
| Síntoma | Causa | Solución |
|---|---|---|
No hay panel. Error CORS en …/sdk/sessions y error [kaleidr:chat] | La clave es desconocida, está revocada o el origen no está permitido. El servidor solo envía cabeceras CORS a orígenes admitidos. | Comprueba la clave y añade el origen exacto, incluido protocolo y puerto, en kaleidr.com/api-keys. |
[kaleidr:chat] kaleidr session exchange failed (403) | Clave válida, pero sin acceso a Chat. detail puede ser insufficient_scope (sin ai), product_not_allowed (otros productos) o tier_capability_not_allowed. | Usa una clave con ai y permiso para chat. |
[kaleidr:chat] Kaleidr: a server key (kld_sk_…) must never be used in the browser … | Has usado una clave de servidor y no se ha enviado ninguna solicitud. | Usa una clave publicable (kld_pk_live_…). Revoca la de servidor si apareció en una página pública. |
[kaleidr:chat] mount target not found: #chat | El selector no encuentra el destino. | Ejecuta mount cuando exista el elemento o pasa el elemento directamente. mount |
[kaleidr:chat] [kaleidr] failed to load https://cdn.kaleidr.com/embed/v1/chat.js | El bundle está bloqueado por la política de contenido o un bloqueador de anuncios. | Autoriza https://cdn.kaleidr.com en script-src. |
Kaleidr is not defined | El código se ejecutó antes de que terminara de cargar kaleidr.js, por ejemplo con async o defer. | Carga kaleidr.js sin esos atributos antes de tu código o ejecuta tu código en el evento load del script. |
[kaleidr] embed is disabled — … | El control de habilitación está deteniendo los montajes. | El mensaje indica qué control lo estableció. Consulta kaleidr.js. |
| El panel aparece arriba a la izquierda de la ventana, no sobre el mapa | Falta contained o #chat no está posicionado. | Añade contained: true y los estilos del paso 1. |
| El panel responde, pero no aparecen marcadores ni se mueve el mapa | El objeto de map no se reconoce. | Pasa la instancia mapboxgl.Map real. Consulta Mapas compatibles. |
| El mapa vuela a un lugar, pero no aparecen marcadores ni se encuadran varios | No existe window.mapboxgl. Para volar a uno basta con el objeto de mapa, pero los marcadores y el encuadre necesitan ese global. | Si importas Mapbox con npm, define window.mapboxgl antes de montar. Consulta Exponer un import de npm. |
| El panel siempre dice "Sorry — that didn't go through. Please try again." | La sesión ya no es válida porque se revocó la clave o cambiaron los orígenes permitidos. | Comprueba la clave y vuelve a cargar la página. |
| El panel dice "You've reached your usage limit for now." | Error 429: se han agotado los créditos de IA o se alcanzó el límite de la clave. Todos los visitantes comparten el límite de la misma clave. | Consulta Cuotas y límites de frecuencia. |
| El mapa no se puede arrastrar | La capa de chat está interceptando la interacción. | Añade pointer-events:none a #chat. |
Encontrarás más síntomas en Solución de problemas.
Limitaciones
- Tu página no recibe callbacks ni eventos del panel: no puedes reaccionar por código a una pregunta, respuesta o clic en un marcador.
- El asistente no ve tus capas, marcadores ni la zona que muestra el mapa. Solo se envía el nivel de zoom junto a la pregunta.
- No puedes enviar instrucciones ni datos propios al asistente mediante el panel.
- El idioma de las respuestas, título y placeholder se configura al montar (
lang,title,placeholder): consulta Referencia de Chat. Las demás etiquetas están en inglés. handle.setCamera()no tiene efecto en un chat montado y produce una advertencia. Mueve la cámara con la API propia de Mapbox.- En una aplicación de una sola página, llama a
handle.destroy()al eliminar la vista del mapa y vuelve a montar cuando regrese.
La lista completa está en Capacidades y límites.
Próximos pasos
- Temas y disposición: adapta el panel a tu sitio.
- Referencia de Chat: opciones, handle y errores.
- Lista de verificación de producción: qué revisar antes de publicar.
- Frameworks: integración desde React, Next.js y Vue.