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
| Requisito | Detalle |
|---|---|
| HTTPS | Obligatorio (excepto localhost) |
| Navegadores | Chrome, Safari, Edge |
| Permisos | Acceso al micrófono |
Idiomas soportados
| Idioma | Código | Precisión |
|---|---|---|
| Español | es-ES | Alta |
| Inglés | en-US | Alta |
El idioma se detecta automáticamente según la configuración locale del widget.
Cómo funciona
- Usuario hace clic en el icono de micrófono
- Se solicita permiso del micrófono (primera vez)
- El widget muestra "Escuchando..."
- Usuario dicta su búsqueda
- 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
| Formato | Extensión | Soporte |
|---|---|---|
| JPEG | .jpg, .jpeg | Completo |
| PNG | .png | Completo |
| WebP | .webp | Completo |
| GIF | .gif | Solo primer frame |
| HEIC | .heic | Conversión automática |
Límites
| Parámetro | Valor |
|---|---|
| Tamaño máximo | 5 MB |
| Resolución mínima | 100x100 px |
| Resolución máxima | 4096x4096 px |
Métodos de entrada
- Subir archivo: Click en el icono de cámara → Seleccionar archivo
- Arrastrar y soltar: Drag & drop de imagen sobre el widget
- Captura de cámara: En móviles, opción de tomar foto
Cómo funciona
- Usuario sube/captura una imagen
- Imagen se redimensiona si es necesario (máx 1024px)
- Se envía al backend para análisis
- El motor genera embeddings de imagen (OpenCLIP)
- Se buscan productos visualmente similares
- 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
| Evento | Payload | Descripció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
- Comparación de Productos - Comparar resultados
- Accesibilidad - Cumplimiento WCAG
- JavaScript API - Control programático