Skip to main content

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:
1

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.
2

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.
3

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

Example 1: Form-Based Integration

Integrate the widget with an HTML form for address input:
index.html
<!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:
direct-integration.html
<!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:
HumWidget.jsx
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:
HumWidget.vue
<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: 20px;
  color: red;
  border: 1px solid red;
  border-radius: 4px;
  margin-bottom: 20px;
}
</style>

Address Data Format

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:
  • street1: Primary address (street number and name)
  • city: Valid city name
  • state: Valid 2-letter US state code
  • zip: 5 or 9-digit ZIP code format (12345 or 12345-6789)
  • 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
  • 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

Check these common issues:
  • Verify the container div exists on the page
  • Ensure the widget script loads before your initialization code
  • Check that your API key is valid and properly formatted
  • Look for JavaScript errors in the browser console
Expected behavior: The widget should initialize within 2-3 seconds of calling hum.initialize().
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.
Optimization tips:
  • Include latitude and longitude coordinates when available
  • Use the summary layout for faster loading when full e-commerce isn’t needed
  • Ensure the widget script is loaded asynchronously
  • Check network connectivity and CDN availability
Expected behavior: The widget should load service options in under 10 seconds for most addresses.
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;
}
  • Load the widget script asynchronously
  • Include latitude/longitude coordinates for faster results
  • Cache widget instances when using multiple widgets
  • Monitor console logs during development
  • 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