useVoiceCommands

Hook for reactive non-dictation voice commands (play, pause, seek, etc.)

import { useVoiceCommands } from "@roku-sdk/runtime/voice-commands";
useVoiceCommands(): VoiceCommandHook

Description

Hook for reactive non-dictation voice commands (play, pause, seek, etc.).

Firmware routes media and navigation voice commands through the voice input handler. This hook hides that wiring: it subscribes to useInput internally and exposes a single commandParams signal filtered to events whose command is not "dictation".

Unlike useVoiceDictation, this hook does not auto-acknowledge events. The app must call respond(status) with an appropriate VoiceHandledStatus once it has handled (or declined) the command. Firmware blocks up to 5s per event until the app responds.

Because the ack is the app's job, commandParams is published synchronously as each event arrives: consumers run — and get a chance to respond — before the next command can overwrite the signal. Deferring the publish would let two commands arriving back to back collapse into one, leaving the first unanswered until firmware times it out.

Return values

VoiceCommandHook with a reactive commandParams accessor and a respond method to acknowledge the latest command.

Example

const { commandParams, respond } = useVoiceCommands();

createEffect(() => {
    const params = commandParams();
    if (!params) return;
    switch (params.command) {
        case "play":
            startPlayback();
            respond("success");
            break;
        case "pause":
            pausePlayback();
            respond("success");
            break;
        default:
            respond("unhandled");
    }
});

Types

VoiceCommandHook

Return type for the useVoiceCommands hook.

type VoiceCommandHook = {
    commandParams: Accessor<VoiceInputParams | null>;
    respond: (status: VoiceHandledStatus) => boolean;
};
NameTypeDescription
commandParamsAccessor<VoiceInputParams | null>Reactive accessor for the latest non-dictation voice input event. Returns null until the first command arrives.
respond(status: VoiceHandledStatus) => booleanAcknowledge the most recent command with a VoiceHandledStatus. Firmware blocks up to 5s per event until the app responds (equivalent to roInput.EventResponse). Call it while handling the command — once the next command is published, respond targets that one.

What’s Next

Did this page help you?