Getting Started

As a site owner, you can embed the Voice Box script tag to enable voice for your visitors. In general, Voice Box is able to control most sites without any additional effort on your part. Include the script tag right before the closing body tag.

<script src="https://www.voicebox.tel/js/voicebox.js"></script>

Of course, every site is unique, so in order for you to give users the best experience when voice controlling your site, you may choose to annotate your HTML with various commands which will help Voice Box know which elements to target and which ones to avoid. For example, when users say "scroll down" it might not work on your site if your document body does not scroll. However, by annotating the correct HTML element with the vbx-scroll attribute, users will experience the correct behavior.

Alexa Setup

Click "Enter security code" to connect any Alexa device.

Say "Alexa, ask Voice Box to sign out" to completely disconnect your browser from your Alexa device.

Contents

This guide details how to do common browsing tasks like scrolling and clicking links by using your voice. Refer to each section for the proper way to phrase a command. Pay particular attention to the section on forms. The system is flexible, but it helps to be more precise in order to have the best experience.

Your Voice Box experience works best if you understand how voice box annotates the page. For example, consider this set of form fields.

Fields

If you want to un-check the box called "Not a robot", you would begin by saying,

Alexa, ask Voice Box to number the fields.

Numbers will now appear next to each field element in the visibly scrolled region. Scrolling the page up and down will cause the elements to renumber, allowing you to target visible fields by their number.

Annotated Fields

It is now possible to un-check the box by saying,

Alexa, ask Voice Box to uncheck field 7.

If you've used a mapping app before, this is similar to adding markers to the map for nearby restaurants. As you move the map, the markers redraw to annotate the newly visible region.

Refer to the following sections for commands and tips as you learn to voice browse.

Scrolling

The scrolling commands are used to scroll the page up and down.

User commands

Alexa, ask Voice Box to...
Command Event ID
Scroll Up page_scroll_up
Scroll Down page_scroll_down
Scroll to the top page_scroll_top
Scroll to the bottom page_scroll_bottom

Whitelist

Use a whitelist to enable voice-based scrolling for specified types. In the following example, only the page_scroll_top and page_scroll_bottom events will still run. All other scroll event types are suppressed.

                
<head>
    <meta name="vbx-whitelist" target="page_scroll_top, page_scroll_bottom">
</head>
                
                

Blacklist

Use a blacklist to suppress voice-based scrolling for the specified event types. In the following example, the page_scroll_up and page_scroll_down events are suppressed. All other scroll event types are still honored, including the page_scroll_top and page_scroll_bottom events.

                
<head>
    <meta name="vbx-blacklist" target="page_scroll_up, page_scroll_down">
</head>
                
                

Custom Attributes

By default, the HTML document body is the target for scroll events. You can change the target by annotating the desired element with the vbx-scroll attribute.

                
<div id="scrollable_div" vbx-scroll> </div>
                
                

Before Event Handlers

Use a before event handler to intercept scroll-related commands before Voice Box processes them. Return a Boolean false to suppress the event. Note that if an event is suppressed, the after event will not fire. In the following example, an element other than the document body is being scrolled when a voice command is processed. The amount of the scroll as well as the speed (500ms) are both customized as well.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {
                page_scroll_up: function () {
                    var target = jQuery('#scrollable_div');
                    var amt = (target.scrollTop() - (target[0].clientHeight * .87);
                    target.animate( {scrollTop: amt}, 500);
                    return false;
                },

                page_scroll_down: function() {
                    var target = jQuery('#scrollable_div');
                    var amt = (target.scrollTop() + (target[0].clientHeight * .87);
                    target.animate( {scrollTop: amt}, 500);
                    return false;
                 },

                page_scroll_top: function() {
                    var target = jQuery('#scrollable_div');
                    target.animate( {scrollTop: 0}, 500);
                    return false;
                },

                page_scroll_bottom: function() {
                    var target = jQuery('#scrollable_div');
                    target.animate( {scrollTop: target.height()}, 500);
                    return false;
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handlers

Use an after event handler to process commands after Voice Box. In the following configuration, the page_scroll_down and page_scroll_bottom event handlers check for new content to append to the page.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                page_scroll_down: function() {
                    check_for_new_content();
                },

                page_scroll_bottom: function() {
                    check_for_new_content();
                }
            }
        }
   }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

History

Navigate the browser history. This is equivalent to clicking the back and next buttons on the browser toolbar.

Alexa, ask Voice Box to...
Command Event ID
Go back history_nav_back
Go forward history_nav_forward

Whitelist

Use a whitelist to enable voice-based navigation for a single navigational direction. This example only allows the user to navigate back. The navigate forward command will be suppressed.

                
<head>
    <meta name="vbx-whitelist" target="history_nav_back">
</head>
                
                

Blacklist

Use a blacklist to suppress voice-based navigation for an event type. This example suppresses both navigational events (back and forward).

                
<head>
    <meta name="vbx-blacklist" target="history_nav_back, history_nav_forward">
</head>
                
                

Before Event Handler

Use a before event handler to intercept navigation-related commands. Return a Boolean false to suppress. The history_nav_forward and history_nav_back event types are supported. Returning false for both events as shown here is equivalent to adding a vbx-blacklist meta element as described in the section above.

                
<!-- Include voice box config -->
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {
                history_nav_forward: function () {
                    return false;
                },

                history_nav_back: function() {
                    return false;
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handler

There are no supported after event handlers for the history event types.

Find Text

The Find Text feature allows you to search for text in the page. If one or more results are found, they will be highlighted. By default, Voice Box will search for text within span, div, label, and p elements.

User Commands

Alexa, ask Voice Box to...
Command Event ID
Find text text_find
Show the next result text_next
Show the prior result text_back
Show result 2 text_goto
Replace text text_replace
Stop highlighting search results text_hide

Whitelist

For security reasons, the replace text feature is disabled. Enable it using a whitelist meta tag.

                
<head>
    <meta name="vbx-whitelist" target="text_replace">
</head>
                
                

Blacklist

Use a blacklist to suppress find-related events. In the following example, text_back, text_next and text_goto are all blacklisted. Only text_find is allowed, meaning a user could still highlight text on the screen by issuing the Find Text command. But they would not be able to navigate through the search results.

                
<head>
    <meta name="vbx-blacklist" target="text_goto, text_next, text_back">
</head>
                
                

Before Event Handler

Use a before event handler to intercept the navigation command. Return a Boolean false to suppress an event from being handled by Voice Box. In this example the text_replace event has been enabled (it is disabled by default). This is equivalent to using the whitelist approach described above. In addition, a text_find handler has been included that only looks for p elements. (By default, Voice Box looks for for text within span, div, label, and p elements.)

                
<!-- Include voice box config -->
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {
                text_replace: function(msg) {
                    var all = jQuery("span[voicebox-text]");
                    if(all.length) {
                        all.each(function (index, elm) {
                            elm = jQuery(elm);
                            elm.text(msg.value);
                        });
                        VoiceBox.injector.do.toast(all.length + " search results were replaced.");
                    } else {
                        VoiceBox.injector.do.toast("There are no search results to replace.");
                    }
                    return false;
                },

                text_find: function (msg) {
                    handlers.action.set_annotation_type("text");
                    if(msg.value != "") {
                        var counter = 0;
                        function replace_with() {
                            counter++;
                            return counter > 99 ? msg.value : jQuery("<span voicebox-text=\"true\" tabindex=\"-1\" style=\"background-color:yellow;\">" + msg.value + "</span>");
                        }
                        jQuery("p").replaceText(msg.value, replace_with);
                        if (counter) {
                            injector.do.toast(counter + " instances found. Say \"show next result\".");
                            handlers.action.text_goto({value:1});
                        } else {
                            injector.do.toast("The search text was not found.");
                        }
                    } else {
                        injector.do.toast("The search text was empty. Try again.");
                    }
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handler

The after event handlers for find-related events can be used to modify the markup. For example, you may choose to change the highlight color for every found element to better match the color palette for your site.

                
<!-- Include voice box config -->
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                text_replace: function(msg) {
                    //make the links orange instead of red
                    jQuery("*[voicebox-text]").each(function (index, elm) {
                        jQuery(elm).css({"backgroundColor":"orange"});
                    });
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

Headings

Use the Headings commands to annotate all heading elements on a page (not just those that are scrolled into view). Headings are numbered from 1 to 20, beginning with the first heading in the document. For example, if you say, "Alexa, tell voice box to go to heading 1", you will be scrolled to the top of this document.

User Commands

Alexa, ask Voice Box to...
Command Event ID
Number the headings outline_show
Go to heading 8 outline_goto
Go to the next heading outline_next
Go to the prior heading outline_back
Stop numbering the headings outline_hide

Whitelist

Use a whitelist to identify specific headings that should be annotated/numbered. Note that annotating a single heading element with this flag will result in every other heading element being excluded unless it too is explicitly annotated. In this example, only the first two headings listed would be annotated, since they include the vbx-whitelist attribute.

                
<h1 vbx-whitelist>My Document Title</h1>
<h2 vbx-whitelist>My First Subsection</h1>
<h2>My Second Subsection</h1>
                
                

Blacklist

Use a blacklist to suppress heading-related events. In the following example, outline_goto, outline_next and outline_back are all blacklisted. Only outline_show is allowed, meaning a user could still number the headings by saying Number the headings. But they would not be able to navigate through each annotated heading.

                
<head>
    <meta name="vbx-blacklist" target="outline_goto, outline_next, outline_back">
</head>
                
                

Use a blacklist to suppress specific headings as well. In this case, the <h1> element in the document will not be annotated along with other headings when the command is issued to "Number the headings".

                
<h1 vbx-blacklist>My Document Title</h1>
                
                

Before Event Handler

Use a before event handler to intercept the event before Voice Box. Return a Boolean false to suppress the event from being handled by Voice Box. The following fully suppresses all outline-related commands.

                
<!-- Include voice box config -->
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {
                outline_show: function(msg) {
                    return false;
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handler

The after event handlers for heading-related events can be used to modify the markup. For example, you may choose to change the highlight color for every found heading to better match the color palette for your site.

                
<!-- Include voice box config -->
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                outline_show: function(msg) {
                    //make the links orange instead of red
                    jQuery("div[voicebox-link]").each(function (index, elm) {
                        jQuery(elm).css({"backgroundColor":"orange"});
                    });
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

Tables

Use Table commands to sort a table by a particular column and change the sort direction. When tables are numbered, only visible tables and columns will have numbers. By default, the markers used for table numbers use a white background while column numbers use a red background.

User Commands

Alexa, ask Voice Box to...
Command Event ID
Number the tables table_show
Sort column 4 table_sort
Sort the other direction table_sort_direction
Stop numbering tables table_hide
Name Description Price
Item One Ante turpis integer aliquet porttitor. 29.99
Item Two Vis ac commodo adipiscing arcu aliquet. 19.99
Item Three Morbi faucibus arcu accumsan lorem. 99.99
Item Four Vitae integer tempus condimentum. 49.99
Item Five Turpis integer aliquet porttitor. 79.99
100.00

Whitelist

Use the whitelist approach to specify which tables in a page can be targeted. The following will only add markers to the first table, since it is the only one to declare the vbx-whitelist attribute. If no tables declare this attribute, then all tables will be targeted.

                
<table vbx-whitelist>...</table>
<table>...</table>
<table>...</table>
                
                

Blacklist

Use the blacklist approach to specify which tables in a page cannot be targeted. The following table will not be targeted.

                
<table vbx-blacklist>...</table>
                
                

Before Event Handlers

Use a before event handler to intercept table-related commands before Voice Box processes them. Return a Boolean false to cancel.

In the following example, the table_sort event is intercepted and cancelled. Instead, a custom function is called that will sort the table using a function that is appropriate to the framework involved (do_sort). This is helpful for MVC frameworks like AngularJS, where sorting the Model ultimately causes the View to re-render. Note that the function returns false to ensure that the default sort function is not run.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {

               /**
                * sort a table based upon a given column. supports both ascending and descending sorts.
                * @param msg {object}
                * @param msg.value {object}
                * @param msg.value.position {number|string} 1-based index for the annotated column
                * @param [msg.value.direction] {string} one of: ascending, descending
                */
                table_sort: function(msg) {
                    do_sort(msg.value.position, msg.value.direction);
                    return false;
                }
            }
        }
   }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handlers

Use an after event handler to process commands after Voice Box. In the following configuration, the table_show event handler changes the background color for all link markers to orange. Markers are standard HTML elements that can be styled and positioned.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                table_show: function () {
                    //make the links orange instead of red
                    jQuery("div[voicebox-link]").each(function (index, elm) {
                        jQuery(elm).css({"backgroundColor":"orange","color":"white"});
                    });
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

Forms & Fields

The Field commands are used to fill out forms, check boxes, select radio buttons, and click buttons. Voice Box is flexible, but some fields (like checkboxes) are easier to update if you use a specific command. Also note that Alexa is not intended as a dictation device, so long phrases can be difficult to process when dictating free-form text into fields.

User Commands

Alexa, ask Voice Box to...
Command Event ID Supported Fields
Number the fields field_show button, checkbox, text input, radio
Choose field # field_update_elicit button (click), checkbox (check), radio (choose)
Un-check Field #
Check Field #
field_update_elicit checkbox (check), radio (choose)
Click Field # field_update_elicit button (click), checkbox (toggle), radio (choose)
Update Field #* field_update_elicit text input
Focus Field # field_focus_goto button, checkbox, text input, radio
Focus next field field_focus_next button, checkbox, text input, radio
Focus prior field field_focus_back button, checkbox, text input, radio
Stop numbering fields field_hide button, checkbox, text input, radio
*When you request Alexa to update a text input field, Alexa will prompt for the value (e.g., "OK, what value should I enter into Field 1?")

Whitelist

Use the whitelist approach to specify which fields in a page can be targeted. The following will only add markers to the first field, since it is the only one to declare the vbx-whitelist attribute. If no fields declare this attribute, then all fields will be targeted.

                
<input type="text" name="demo-name" vbx-whitelist/>
<input type="text" name="demo-number"/>
                
                

Blacklist

Use the blacklist approach to specify which fields in a page cannot be targeted. The following field will not be targeted.

                
<input type="text" name="demo-name" vbx-blacklist/>
                
                

Before Event Handlers

Use a before event handler to intercept field-related commands before Voice Box processes them. Return a Boolean false to cancel.

In the following example, the field_update_elicit event is intercepted and cancelled. This handler is called by Voice Box when the user attempts to update a field. It is used to get details about the field (such as its title and type) in order to improve the user experience. For example, when the user tells Alexa to "Update field 2", Voice Box will call field_update_elicit to request the field metadata. If you wish to ensure that no metadata is ever sent, you can choose instead to manually override this method and send a generic field label such as "Field 2".

At this time, only the literal data type is supported as is shown in the example below. In the next release of Voice Box we will include support for other types such as street, city, state, etc. This helps Alexa accurately interpret the user's response when provided.

Finally, the field_update_value handler is called once the user has provided a value to Alexa. In the custom implementation shown here, checkbox and radio buttons are handled differently to ensure they are properly checked and unchecked.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {

               /**
                * The user has asked to "Update field {position}". Send the field data type and title to Alexa.
                *
                * @param msg {object}
                * @param msg.value {object}
                * @param msg.value.url {string} where to send the metadata for the field, so Alexa can read it
                * @param msg.value.position {number|string} 1-based index for the annotated field on-screen to fill out
                * @param msg.value.code {string} single-use guid that must be echoed to the server
                */
                field_update_elicit: function(msg) {
                    var field = jQuery("*[voicebox-linked=" + msg.value.position + "]");
                    if (field.length) {
                        //bind guid to the targeted field in case the user scrolls away and the position is lost
                        field.attr("voicebox-linked-code", msg.value.code);
                        //send field title and type to Alexa (to be read aloud to the user by Alexa)
                        sendMessage({
                            type: "action",
                            subtype: "field_update_metadata",
                            value: {
                                title: "Field number " + msg.value.position,
                                type: field.attr("type") || "select",
                                url: msg.value.url,           //echo; required to resolve the server address
                                position: msg.value.position, //echo; required to identify the field position
                                code: msg.value.code          //echo; required for field correlation in the next step
                            },
                            auth: msg.auth                    //echo; required for local security
                        });
                    } else {
                        VoiceBox.injector.do.toast("Update Failed | Field " + msg.value.position + " not found.");
                    }
                    return false;
                },

              /**
                * Alexa read the question to the user. The user responded with a value. Insert value into target field.
                *
                * @param msg {object}
                * @param msg.value {object}
                * @param msg.value.value {string} the value to enter for the field (as provided/interpreted by Alexa)
                * @param msg.value.code {string} guid identifying the specific field to update.
                */
                field_update_value: function (msg) {
                    var field = jQuery("*[voicebox-linked-code=" + msg.value.code + "]");
                    if (field.length) {
                        var type = field.attr("type");
                        field.val(msg.value.value);
                        var val = msg.value.value.toLowerCase();
                        if (type == "checkbox" || type == "radio") {
                            field.prop('checked', val == "true" || val == "checked" || val == "check" || val == "select" || val == "selected");
                        }
                    }
                    return false;
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handlers

Use an after event handler to process commands after Voice Box. In the following configuration, the field_update_value event handler sends an alert message that the field was updated.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                field_update_value: function (msg) {
                    var field = jQuery("*[voicebox-linked-code=" + msg.value.code + "]");
                    if (field.length) {
                        VoiceBox.injector.do.toast("Field " + msg.value.position + " was updated to " msg.value.value);
                    }
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

Images

Zoom in on targeted images. Create a slide show.

Alexa, ask Voice Box to...
Command Event ID
Number the images image_show
Zoom in on image 1 image_zoom_in
Zoom out image_zoom_out
Start a slideshow image_slide_start
Stop the slideshow image_slide_end
Stop numbering images image_hide
Arches
Matterhorn
Fields of Gold
Rolling Hills
Water Droplets
Colorado Plateau
Half Dome
Rocky Mountains
Aurora Borealis
Splish Splash

Whitelist

Use the whitelist approach to specify which images in a page can be targeted. The following will only add markers to the first image, since it is the only one to declare the vbx-whitelist attribute. If no images declare this attribute, then all images will be targeted.

                
<img url="/image1.jpg" vbx-whitelist>
<img url="/image2.jpg">
                
                

Blacklist

Use the blacklist approach to specify which images cannot be targeted. The following image will not be targeted.

                
<img url="/image1.jpg" vbx-blacklist>
                
                

The blacklist can be more specific if necessary, and isolated to a specific event. For example, here the first image cannot be targeted for a slideshow while the second image may not be targeted in any context.

                
<img url="/image1.jpg" vbx-blacklist="image_slide_start">
<img url="/image2.jpg" vbx-blacklist>
                
                

Before Event Handlers

Use a before event handler to intercept image-related commands before Voice Box processes them. Return a Boolean false to cancel. In the following example, the image_zoom_in command is intercepted and a custom implementation ensures the image is fully contained within the page. (The default implementation provided by VoiceBox clips some of the image in ordr to fully cover the screen.)

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            before: {

              /**
                * zoom in on an image at a numbered position
                *
                * @param msg {object}
                * @param msg.value {number|string} 1-based number
                */
                image_zoom_in: function (msg) {
                    var img = jQuery("img[voicebox-linked=" + msg.value + "]");
                    if (img[0]) {
                            var src = img.attr("src");
                            var strHTML = '<div style="width:100%;height:100%;box-sizing:content-box;background-size:contain;background-position:center center;background-repeat:no-repeat;background-image:url(' + src + ');"> </div>';
                            VoiceBox.injector.do.overlay(strHTML);
                            //show the the image alt tag (which is usually its name)
                            if(img.attr("alt")) {
                                VoiceBox.injector.do.toast(img.attr("alt"));
                            }
                    } else {
                        VoiceBox.injector.do.toast("Image " + msg.value + " not found.");
                    }
                    return false;
                },
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>
                
                

After Event Handlers

Use an after event handler to process commands after Voice Box. In the following configuration, the image_show event handler changes the background color for all link markers to green. Markers are standard HTML elements that can be styled and positioned.

                
<script>
    var VoiceBoxConfig = {
        handlers: {
            after: {
                image_show: function () {
                    //make the links orange instead of red
                    jQuery("div[voicebox-link]").each(function (index, elm) {
                        jQuery(elm).css({"backgroundColor":"green","color":"white"});
                    });
                }
            }
        }
    }
</script>

<!-- Include voice box -->
<script src="https://www.voicebox.tel/js/voicebox.js"></script>