JavaScript Widget Integration The Hum widget can be embedded directly into your website with just a few lines of JavaScript and HTML. This integration method is ideal for web applications, landing pages, and any environment where you have control over the HTML and JavaScript. 
This guide covers the JavaScript/HTML embed integration. For mobile app WebView integration, see WebView Integration . Quick Start Get up and running with the Hum widget in three simple steps: 
Add the Widget Container
Add a container div where you want the widget to render: < div  id = "hum-widget" ></ div > You can customize the container ID, but make sure it matches the element you pass to the widget constructor. 
Include the Widget Script
Load the Hum widget script in your HTML page: < script  src = "https://cdn.letshum.com/widget.js" ></ script > The script loads asynchronously and is hosted on a CDN for optimal performance. 
Initialize the Widget
Initialize the widget with your API key: const  hum  =  new  HUM (     'YOUR_API_KEY_HERE' ,     document . getElementById ( 'hum-widget' ) ); hum . initialize (); // Store the instance globally for access by other components window . humInstance  =  hum ; Verify the widget loads by checking your browser’s developer console for any error messages. 
Configuration The Hum widget accepts an optional configuration object as the third parameter. For a complete list of available options, see the Widget Overview . 
Basic Configuration Example const  hum  =  new  HUM (     'YOUR_API_KEY_HERE' ,     document . getElementById ( 'hum-widget' ),     {         resultLayout:  'checkout' ,         primaryColor:  '#1274f9' ,         campaignId:  'Q4-2024-campaign'     } ); hum . initialize (); Advanced Configuration Example Here’s a comprehensive example with all available options: 
const  hum  =  new  HUM (     'your-api-key' ,     document . getElementById ( 'hum-widget' ),     {         // Display & Layout         resultLayout:  'checkout' ,         primaryColor:  '#1274f9' ,         showSavePlanButton:  true ,   // Enable save/unsave plan button                  // Tracking & Analytics         campaignId:  'Q4-2024-landing-page' ,                  // Filtering & Limiting         limitProviders:  [ '130077' ,  '130317' ],         primaryProviders:  [ '130077' ],         limitTechnologies:  [ 'Fiber' ,  'Cable' ,  'Wireless' ],                  // Customer Data Pre-population         customerData:  {             firstName:  'Jane' ,             lastName:  'Smith' ,             email:  'jane.smith@example.com' ,             phoneNumber:  '555-987-6543'         }     } ); hum . initialize (); Integration Examples Integrate the widget with an HTML form for address input: 
<! DOCTYPE  html > < html > < head >     < title > Hum Widget Demo </ title >     < script  src = "https://cdn.letshum.com/widget.js" ></ script > </ head > < body >     <!-- Widget container -->     < div  id = "hum-widget" ></ div >     <!-- Address input form -->     < form  id = "address-search" >         < input  type = "text"  name = "street1"  placeholder = "Street Address"  required >         < input  type = "text"  name = "street2"  placeholder = "Apartment/Suite (Optional)" >         < input  type = "text"  name = "city"  placeholder = "City"  required >         < input  type = "text"  name = "state"  placeholder = "State (2 letters)"  maxlength = "2"  required >         < input  type = "text"  name = "zip"  placeholder = "ZIP Code"  pattern = "[0-9]{5}(-[0-9]{4})?"  required >         < input  type = "hidden"  name = "campaign_id"  value = "your-campaign-id" >         < button  type = "submit" > Check Availability </ button >     </ form >     < script >         // Initialize Hum widget         const  hum  =  new  HUM (             'hum_live_1234567890abcdef' ,             document . getElementById ( 'hum-widget' )         );                  hum . initialize ()             . then (()  =>  {                 console . log ( 'Hum widget initialized successfully' );             })             . catch ( error  =>  {                 console . error ( 'Failed to initialize Hum widget:' ,  error );                 document . getElementById ( 'hum-widget' ). innerHTML  =                       '<p style="color: red;">Unable to load widget. Please try again later.</p>' ;             });         window . humInstance  =  hum ;         // Handle form submission         document . getElementById ( 'address-search' ). addEventListener ( 'submit' ,  async  ( event )  =>  {             event . preventDefault ();                          const  submitButton  =  event . target . querySelector ( 'button[type="submit"]' );             const  originalText  =  submitButton . textContent ;             submitButton . textContent  =  'Loading...' ;             submitButton . disabled  =  true ;                          try  {                 const  formData  =  new  FormData ( event . target );                 const  addressData  =  Object . fromEntries ( formData . entries ());                                  // Remove empty optional fields                 if  ( ! addressData . street2 )  delete  addressData . street2 ;                 if  ( ! addressData . campaign_id )  delete  addressData . campaign_id ;                 // Validate required fields                 if  ( ! addressData . street1  ||  ! addressData . city  ||  ! addressData . state  ||  ! addressData . zip ) {                     throw  new  Error ( 'Please fill in all required fields' );                 }                 // Submit address to widget                 const  sessionToken  =  await  hum . internetServiceFromAddress ( addressData );                 console . log ( 'Widget loaded with session token:' ,  sessionToken );                              }  catch  ( error ) {                 console . error ( 'Error loading internet service options:' ,  error );                 alert ( 'Unable to load internet service options. Please check your address and try again.' );             }  finally  {                 submitButton . textContent  =  originalText ;                 submitButton . disabled  =  false ;             }         });     </ script > </ body > </ html > Test your integration by entering a valid US address and verifying that service options load correctly. 
Example 2: Direct Address Loading Load address data directly when you already have the information: 
<! DOCTYPE  html > < html > < head >     < title > Hum Widget - Direct Integration </ title >     < script  src = "https://cdn.letshum.com/widget.js" ></ script > </ head > < body >     < div  id = "hum-widget" ></ div >     < script >         const  hum  =  new  HUM (             'hum_live_1234567890abcdef' ,             document . getElementById ( 'hum-widget' ),             {                 resultLayout:  'summary'             }         );                  window . humInstance  =  hum ;         // Address data in the required format         const  addressData  =  {             street1:  "1001 Woodward Ave" ,             street2:  "Suite 500" ,             city:  "Detroit" ,             state:  "MI" ,             zip:  "48226" ,             campaign_id:  "summer-2024" ,             latitude:  42.3317 ,             longitude:  - 83.0479         };         // Initialize and load address data         async  function  loadWidget () {             try  {                 await  hum . initialize ();                 console . log ( 'Hum widget initialized successfully' );                                  const  sessionToken  =  await  hum . internetServiceFromAddress ( addressData );                 console . log ( 'Internet service options loaded:' ,  sessionToken );                              }  catch  ( error ) {                 console . error ( 'Widget initialization failed:' ,  error );                                  const  container  =  document . getElementById ( 'hum-widget' );                 container . innerHTML  =  `                     <div style="padding: 20px; border: 1px solid #e74c3c; background: #fadbd8; color: #c0392b; border-radius: 4px;">                         <h3>Unable to Load Internet Service Options</h3>                         <p>We're having trouble loading service options for this address. Please try again later.</p>                         <p><strong>Error:</strong>  ${ error . message } </p>                     </div>                 ` ;             }         }         if  ( document . readyState  ===  'loading' ) {             document . addEventListener ( 'DOMContentLoaded' ,  loadWidget );         }  else  {             loadWidget ();         }     </ script > </ body > </ html > Use direct integration when you already have address data from a previous form, user profile, or application state. 
Example 3: React Integration Integrate the Hum widget into a React application: 
import  React , {  useEffect ,  useRef ,  useState  }  from  'react' ; function  HumWidget ({  apiKey ,  addressData ,  config  }) {   const  containerRef  =  useRef ( null );   const  humInstanceRef  =  useRef ( null );   const  [ isLoading ,  setIsLoading ]  =  useState ( true );   const  [ error ,  setError ]  =  useState ( null );   useEffect (()  =>  {     // Initialize widget     const  initializeWidget  =  async  ()  =>  {       try  {         setIsLoading ( true );         setError ( null );         // Create HUM instance         const  hum  =  new  window . HUM (           apiKey ,           containerRef . current ,           config         );         await  hum . initialize ();         humInstanceRef . current  =  hum ;         // Load address if provided         if  ( addressData ) {           await  hum . internetServiceFromAddress ( addressData );         }         setIsLoading ( false );       }  catch  ( err ) {         console . error ( 'Failed to initialize Hum widget:' ,  err );         setError ( err . message );         setIsLoading ( false );       }     };     if  ( containerRef . current ) {       initializeWidget ();     }     // Cleanup     return  ()  =>  {       if  ( humInstanceRef . current ) {         // Cleanup logic if needed         humInstanceRef . current  =  null ;       }     };   }, [ apiKey ,  addressData ,  config ]);   // Method to update address   const  updateAddress  =  async  ( newAddress )  =>  {     if  ( humInstanceRef . current ) {       try  {         await  humInstanceRef . current . internetServiceFromAddress ( newAddress );       }  catch  ( err ) {         console . error ( 'Failed to update address:' ,  err );         setError ( err . message );       }     }   };   if  ( error ) {     return  (       < div  style = { {  padding:  '20px' ,  color:  'red' ,  border:  '1px solid red'  } } >         Error loading widget:  { error }       </ div >     );   }   return  (     < div >       { isLoading  &&  < div > Loading widget... </ div > }       < div  ref = { containerRef }  id = "hum-widget"  />     </ div >   ); } // Usage function  App () {   const  addressData  =  {     street1:  "1001 Woodward Ave" ,     city:  "Detroit" ,     state:  "MI" ,     zip:  "48226"   };   const  config  =  {     resultLayout:  'checkout' ,     primaryColor:  '#1274f9' ,     campaignId:  'react-app'   };   return  (     < div >       < h1 > Internet Service Finder </ h1 >       < HumWidget         apiKey = "your-api-key-here"         addressData = { addressData }         config = { config }       />     </ div >   ); } export  default  App ; Example 4: Vue.js Integration Integrate the widget into a Vue.js application: 
< template >   < div >     < div  v-if = " isLoading " > Loading widget... </ div >     < div  v-if = " error "  class = "error" > {{  error  }} </ div >     < div  ref = "widgetContainer"  id = "hum-widget" ></ div >   </ div > </ template > < script > export  default  {   name:  'HumWidget' ,   props:  {     apiKey:  {       type:  String ,       required:  true     },     addressData:  {       type:  Object ,       default:  null     },     config:  {       type:  Object ,       default :  ()  =>  ({})     }   } ,   data ()  {     return  {       humInstance:  null ,       isLoading:  true ,       error:  null     };   } ,   async  mounted ()  {     await  this . initializeWidget ();   } ,   beforeUnmount ()  {     // Cleanup if needed     this . humInstance  =  null ;   } ,   methods:  {     async  initializeWidget () {       try  {         this . isLoading  =  true ;         this . error  =  null ;         // Create HUM instance         this . humInstance  =  new  window . HUM (           this . apiKey ,           this . $refs . widgetContainer ,           this . config         );         await  this . humInstance . initialize ();         // Load address if provided         if  ( this . addressData ) {           await  this . humInstance . internetServiceFromAddress ( this . addressData );         }         this . isLoading  =  false ;       }  catch  ( err ) {         console . error ( 'Failed to initialize Hum widget:' ,  err );         this . error  =  err . message ;         this . isLoading  =  false ;       }     },     async  updateAddress ( newAddress ) {       if  ( this . humInstance ) {         try  {           await  this . humInstance . internetServiceFromAddress ( newAddress );         }  catch  ( err ) {           console . error ( 'Failed to update address:' ,  err );           this . error  =  err . message ;         }       }     }   } } ; </ script > < style  scoped > .error  {   padding :  20 px ;   color :  red ;   border :  1 px  solid  red ;   border-radius :  4 px ;   margin-bottom :  20 px ; } </ style > The widget expects address data in a specific JSON format: 
{   "street1" :  "1001 Woodward Ave" ,   "street2" :  "Suite 500" ,   "city" :  "Detroit" ,   "state" :  "MI" ,   "zip" :  "48226" ,   "campaign_id" :  "Optional Campaign ID" ,   "latitude" :  42.3317 ,   "longitude" :  -83.0479 } For complete field specifications, see the Address Data Format  section in the overview. 
Address Validation The widget validates addresses using these rules: 
Required Field Validation
street1 : Primary address (street number and name)city : Valid city namestate : Valid 2-letter US state codezip : 5 or 9-digit ZIP code format (12345 or 12345-6789) 
Optional Field Validation
street2 : Unit/apartment information (no specific format required)campaign_id : Tracking identifier (no specific format required)latitude/longitude : Must be provided together and within US territorial bounds 
Additional Validation Rules
Address must be geocodable by our system 
Address must be serviceable by at least one provider 
Coordinates must be within the bounds of the US and its territories 
 Troubleshooting 
Address Validation Errors
Common address issues: 
Ensure all required fields (street1, city, state, zip) are provided 
Verify the state is a valid 2-letter US state code 
Check that the ZIP code is in the correct format (12345 or 12345-6789) 
Make sure the address is a real, serviceable US address 
 Expected behavior:  Valid addresses should return service options within 5-10 seconds.
Common integration issues: 
Verify the widget instance is stored globally if accessed by other scripts 
Check for conflicts with other JavaScript libraries 
Ensure proper error handling for failed API calls 
Verify the container element is visible and properly sized 
 Expected behavior:  The widget should integrate seamlessly without affecting other page functionality.If issues persist, check the browser console for detailed error messages and contact support with the specific error details. 
Best Practices 
Always implement proper error handling for API calls: hum . initialize ()     . then (()  =>  console . log ( 'Success' ))     . catch ( error  =>  {         console . error ( 'Error:' ,  error );         // Show user-friendly error message     }); 
Use loading states to improve user experience: button . textContent  =  'Loading...' ; button . disabled  =  true ; try  {     await  hum . internetServiceFromAddress ( addressData ); }  finally  {     button . textContent  =  'Check Availability' ;     button . disabled  =  false ; } 
Test with various address formats and edge cases 
Provide clear error messages 
Use appropriate layouts for your use case 
Include campaign IDs for better tracking 
 Next Steps