Saltar al contenido principal

Búsqueda por Voz e Imagen

El widget permite buscar productos usando voz o imágenes, ofreciendo una experiencia de búsqueda multimodal.

Búsqueda por Voz

Activación

La búsqueda por voz está habilitada por defecto:

NeuroonWidget.init({
features: {
voiceSearch: true, // Por defecto: true
},
});

Requisitos

RequisitoDetalle
HTTPSObligatorio (excepto localhost)
NavegadoresChrome, Safari, Edge
PermisosAcceso al micrófono

Idiomas soportados

IdiomaCódigoPrecisión
Españoles-ESAlta
Inglésen-USAlta

El idioma se detecta automáticamente según la configuración locale del widget.

Cómo funciona

  1. Usuario hace clic en el icono de micrófono
  2. Se solicita permiso del micrófono (primera vez)
  3. El widget muestra "Escuchando..."
  4. Usuario dicta su búsqueda
  5. Se transcribe y ejecuta la búsqueda
// Estados de voz
widget.on('voice:start', () => {
console.log('Micrófono activo');
});

widget.on('voice:end', ({ transcript }) => {
console.log('Transcripción:', transcript);
});

widget.on('voice:error', ({ error }) => {
console.error('Error de voz:', error.message);
});

Manejo de errores

type VoiceError =
| 'not-allowed' // Permiso denegado
| 'no-speech' // No se detectó voz
| 'aborted' // Usuario canceló
| 'network' // Error de red
| 'not-supported'; // Navegador no soportado
widget.on('voice:error', ({ error }) => {
switch (error.code) {
case 'not-allowed':
showNotification('Permite el acceso al micrófono en tu navegador');
break;
case 'no-speech':
showNotification('No te escuché. Inténtalo de nuevo');
break;
case 'not-supported':
showNotification('Tu navegador no soporta búsqueda por voz');
break;
}
});

API de Web Speech

El widget usa la Web Speech API:

// Internamente el widget usa:
const recognition = new webkitSpeechRecognition();
recognition.lang = 'es-ES';
recognition.continuous = false;
recognition.interimResults = true;

Personalizar textos de voz

NeuroonWidget.init({
translations: {
voice: {
listening: 'Te escucho...',
speak: 'Di qué estás buscando',
processing: 'Procesando...',
noMatch: 'No te entendí. ¿Puedes repetir?',
notSupported: 'Tu navegador no soporta búsqueda por voz',
permissionDenied: 'Necesito acceso al micrófono',
},
},
});

Búsqueda por Imagen

Activación

La búsqueda por imagen está habilitada por defecto:

NeuroonWidget.init({
features: {
imageSearch: true, // Por defecto: true
},
});

Formatos soportados

FormatoExtensiónSoporte
JPEG.jpg, .jpegCompleto
PNG.pngCompleto
WebP.webpCompleto
GIF.gifSolo primer frame
HEIC.heicConversión automática

Límites

ParámetroValor
Tamaño máximo5 MB
Resolución mínima100x100 px
Resolución máxima4096x4096 px

Métodos de entrada

  1. Subir archivo: Click en el icono de cámara → Seleccionar archivo
  2. Arrastrar y soltar: Drag & drop de imagen sobre el widget
  3. Captura de cámara: En móviles, opción de tomar foto

Cómo funciona

  1. Usuario sube/captura una imagen
  2. Imagen se redimensiona si es necesario (máx 1024px)
  3. Se envía al backend para análisis
  4. El motor genera embeddings de imagen (OpenCLIP)
  5. Se buscan productos visualmente similares
  6. Resultados ordenados por similitud visual
widget.on('image:upload', ({ file }) => {
console.log('Imagen subida:', file.name, file.size);
});

widget.on('image:result', ({ products }) => {
console.log('Productos similares:', products.length);
});

API de búsqueda por imagen

// Subir imagen programáticamente
const file = document.getElementById('my-file-input').files[0];
await widget.searchByImage(file);

// Con URL de imagen (CORS permitido)
await widget.searchByImageUrl('https://example.com/product.jpg');

Eventos de imagen

EventoPayloadDescripción
image:upload{ file }Imagen seleccionada
image:processing{}Procesando imagen
image:result{ products }Resultados recibidos
image:error{ error }Error en búsqueda
widget.on('image:processing', () => {
showLoadingSpinner();
});

widget.on('image:result', ({ products }) => {
hideLoadingSpinner();
if (products.length === 0) {
showNotification('No encontramos productos similares');
}
});

Manejo de errores de imagen

type ImageError =
| 'invalid-format' // Formato no soportado
| 'file-too-large' // Excede 5MB
| 'resolution-low' // Menos de 100x100
| 'processing-error' // Error del servidor
| 'network'; // Error de red
widget.on('image:error', ({ error }) => {
switch (error.code) {
case 'invalid-format':
showNotification('Usa JPG, PNG o WebP');
break;
case 'file-too-large':
showNotification('La imagen es muy grande (máx 5MB)');
break;
case 'resolution-low':
showNotification('La imagen es muy pequeña');
break;
}
});

Personalizar textos de imagen

NeuroonWidget.init({
translations: {
image: {
upload: 'Sube una foto del producto',
dragDrop: 'Arrastra una imagen aquí',
takePhoto: 'Hacer foto',
searching: 'Buscando productos similares...',
noResults: 'No encontramos productos parecidos',
formatError: 'Formato no válido. Usa JPG, PNG o WebP',
sizeError: 'Imagen muy grande. Máximo 5MB',
},
},
});

Combinando voz e imagen

Puedes usar ambas funcionalidades juntas:

// Búsqueda por imagen + refinamiento por voz
widget.on('image:result', ({ products }) => {
// Mostrar resultados de imagen
displayResults(products);

// Sugerir refinamiento por voz
showPrompt('Di "más baratos" o "solo Nike" para refinar');
});

widget.on('voice:end', ({ transcript }) => {
// Refinar resultados de imagen con voz
const currentFilters = widget.currentFilters;
widget.search(transcript, { filters: currentFilters });
});

Accesibilidad

Ambas funcionalidades están diseñadas con accesibilidad en mente:

Voz

  • Anuncio ARIA cuando el micrófono está activo
  • Feedback visual + sonoro
  • Timeout configurable (10s por defecto)

Imagen

  • Labels descriptivos en botones
  • Feedback de progreso accesible
  • Texto alternativo para resultados
// Los iconos incluyen aria-labels
<button aria-label="Buscar con voz">
<button aria-label="Buscar con imagen">

Desactivar funcionalidades

Si no necesitas estas funcionalidades:

NeuroonWidget.init({
features: {
voiceSearch: false, // Oculta icono de micrófono
imageSearch: false, // Oculta icono de cámara
},
});

Próximos pasos