VoiceSearch
<VoiceSearch // Optional parameters searchAsYouSpeak={boolean} buttonTextComponent={React.Node} statusComponent={React.Node} translations={object} />
About this widget
The VoiceSearch
widget lets the user perform a voice-based query.
It uses the Web Speech API, which only Chrome (from version 25) has implemented so far. This means the voiceSearch
widget only works on desktop Chrome and Android Chrome. It doesn’t work on iOS Chrome, which uses the iOS WebKit.
Examples
1
2
3
import { VoiceSearch } from 'react-instantsearch-dom';
<VoiceSearch />
Props
searchAsYouSpeak
|
type: boolean
default: false
Optional
Whether or not to trigger the search as you speak. If |
||
Copy
|
|||
buttonTextComponent
|
type: React.Node
Optional
Changes the content of the default button (mic icon). It receives the following properties:
|
||
Copy
|
|||
statusComponent
|
type: React.Node
Optional
Changes the content of the status. It receives the same properties as above. |
||
Copy
|
|||
translations
|
type: object
Optional
A mapping of keys to translation values.
|
||
Copy
|
Customize the UI - connectSearchBox
If you want to create your own UI of the VoiceSearch
widget or use another UI library, you can use connectors.
Connectors are higher-order components. They encapsulate the logic for a specific kind of widget and they provide a way to interact with the InstantSearch context.
They have an outer component API that we call exposed props, and they provide some other props to the wrapped components which are called the provided props.
It’s a 3-step process:
// 1. Create a React component
import {
connectSearchBox,
createVoiceSearchHelper
} from 'react-instantsearch-dom';
class VoiceSearch extends React.Component {
componentDidMount() {
const { refine } = this.props;
this.voiceSearchHelper = createVoiceSearchHelper({
searchAsYouSpeak: false,
onQueryChange: query => refine(query),
onStateChange: () => {
this.setState(this.voiceSearchHelper.getState());
},
});
this.setState(this.voiceSearchHelper.getState());
}
componentWillUnmount() {
if (this.voiceSearchHelper) {
this.voiceSearchHelper.dispose();
}
}
render() {
if (!this.voiceSearchHelper) {
return null;
}
const { status, transcript, isSpeechFinal, errorCode } = this.state;
const { isBrowserSupported, isListening, toggleListening } =
this.voiceSearchHelper;
return (
// return the DOM output
);
}
}
/*
this.voiceSearchHelper has the following properties:
- isBrowserSupported: () => boolean
:`true` if user's browser supports voice search.
- isListening: () => boolean
:`true` if listening to user's speech.
- toggleListening: () => void
:Starts listening to user's speech, or stops it if already listening.
- getState: () => object
:returns an object containing the following states regarding speech recognition:
- `status: string`: current status (`initial`|`askingPermission`|
`waiting`|`recognizing`|`finished`|`error`).
- `transcript: string`: currently recognized transcript.
- `isSpeechFinal: boolean`: `true` if speech recognition is finished.
- `errorCode: string|undefined`: an error code (if any).
Refer to the spec for more information.
*/
// 2. Connect the component using the connector
// We re-use `connectSearchBox` here.
const CustomVoiceSearch = connectSearchBox(VoiceSearch);
// 3. Use your connected widget
<CustomVoiceSearch />
Create a React component
class VoiceSearch extends React.Component {
...
render() {
const {
function refine,
} = this.props;
// return the DOM output
}
}
Provided Props
refine
|
type: function
Changes the current query. |
||
Copy
|
Create and instantiate your connected widget
const CustomVoiceSearch = connectSearchBox(VoiceSearch);
<CustomVoiceSearch />
Full example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import {
connectSearchBox,
createVoiceSearchHelper
} from 'react-instantsearch-dom';
class VoiceSearch extends React.Component {
componentDidMount() {
const { refine } = this.props;
this.voiceSearchHelper = createVoiceSearchHelper({
searchAsYouSpeak: false,
onQueryChange: query => refine(query),
onStateChange: () => {
this.setState(this.voiceSearchHelper.getState());
},
});
this.setState(this.voiceSearchHelper.getState());
}
componentWillUnmount() {
if (this.voiceSearchHelper) {
this.voiceSearchHelper.dispose();
}
}
render() {
if (!this.voiceSearchHelper) {
return null;
}
const { status, transcript, isSpeechFinal, errorCode } = this.state;
const { isBrowserSupported, isListening, toggleListening } =
this.voiceSearchHelper;
return (
<div>
<button
type="button"
title="Voice Search"
onClick={toggleListening}
disabled={!isBrowserSupported()}
>
{isListening() ? 'Stop' : 'Start'}
</button>
<div>
<p>status: {status}</p>
<p>transcript: {transcript}</p>
<p>isSpeechFinal: {isSpeechFinal ? 'true' : 'false'}</p>
<p>errorCode: {errorCode}</p>
<p>isListening: {isListening() ? 'true' : 'false'}</p>
<p>isBrowserSupported: {isBrowserSupported() ? 'true' : 'false'}</p>
</div>
</div>
);
}
}
const CustomVoiceSearch = connectSearchBox(VoiceSearch);
HTML output
1
2
3
4
5
6
7
8
<div class="ais-VoiceSearch">
<button class="ais-VoiceSearch-button" type="button" title="Search by voice">
...
</button>
<div class="ais-VoiceSearch-status">
...
</div>
</div>