SpeedOf.Me API - React Integration

This example demonstrates how to integrate the SpeedOf.Me speed test API with React.

Live Demo

Open index.html in your browser to see a working example using CDN builds of React and Babel.

Prerequisites

Quick Start

Option 1: CDN (for quick prototyping)

The index.html file shows how to use React with CDN builds. This is great for demos but not recommended for production.

Option 2: Create React App / Vite (recommended for production)

  1. Create a new React project:
    npm create vite@latest my-speedtest -- --template react
    cd my-speedtest
  2. Add the API script to index.html:
    <script src="https://speedof.me/api/api.js"></script>
  3. Create the SpeedTest hook (src/hooks/useSpeedTest.js):
    import { useState, useEffect, useCallback } from 'react';
    
    export function useSpeedTest({ apiKey, domain, sustainTime = 4 }) {
        const [status, setStatus] = useState('idle');
        const [result, setResult] = useState(null);
        const [progress, setProgress] = useState(null);
        const [error, setError] = useState(null);
    
        useEffect(() => {
            window.SomApi.account = apiKey;
            window.SomApi.domainName = domain;
            window.SomApi.config.sustainTime = sustainTime;
    
            window.SomApi.onTestCompleted = (testResult) => {
                setResult(testResult);
                setProgress(null);
                setStatus('completed');
            };
    
            window.SomApi.onProgress = setProgress;
    
            window.SomApi.onError = (err) => {
                setError(err);
                setStatus('error');
            };
        }, [apiKey, domain, sustainTime]);
    
        const startTest = useCallback(() => {
            setStatus('running');
            setResult(null);
            setError(null);
            window.SomApi.startTest();
        }, []);
    
        return { status, result, progress, error, startTest };
    }
  4. Use the hook in your component:
    import { useSpeedTest } from './hooks/useSpeedTest';
    
    function SpeedTest() {
        const { status, result, progress, error, startTest } = useSpeedTest({
            apiKey: 'YOUR_API_KEY',
            domain: 'your-domain.com'
        });
    
        return (
            <div>
                <button onClick={startTest} disabled={status === 'running'}>
                    {status === 'running' ? 'Testing...' : 'Start Test'}
                </button>
                {result && (
                    <div>
                        <p>Download: {result.download} Mbps</p>
                        <p>Upload: {result.upload} Mbps</p>
                    </div>
                )}
            </div>
        );
    }

Configuration

// Required
window.SomApi.account = 'YOUR_API_KEY';
window.SomApi.domainName = 'your-domain.com';

// Optional
window.SomApi.config.sustainTime = 4;        // 1-8 seconds (higher = more accurate)
window.SomApi.config.testServerEnabled = true;
window.SomApi.config.userInfoEnabled = true;
window.SomApi.config.latencyTestEnabled = true;
window.SomApi.config.uploadTestEnabled = true;

Handling Results

The onTestCompleted callback receives a result object:

{
    download: 150.5,      // Download speed in Mbps
    upload: 25.3,         // Upload speed in Mbps
    latency: 12,          // Latency in ms
    jitter: 2.5,          // Jitter in ms
    testServer: 'LAX',    // Test server location code
    ip_address: '...',    // Client IP (if userInfoEnabled)
    hostname: '...'       // Client hostname (if userInfoEnabled)
}

Progress Updates

The onProgress callback receives progress data during the test:

{
    testType: 'download',     // 'download' or 'upload'
    currentSpeed: 145.2,      // Current speed in Mbps
    percentComplete: 75,      // 0-100
    passNumber: 3             // Current test pass
}

Error Handling

The onError callback receives an error object:

{
    code: 1001,
    message: 'Invalid API key'
}

Common error codes:

Production Considerations

  1. API Key Security: Consider using environment variables and a backend proxy to avoid exposing your API key in client-side code.
  2. Loading State: Show a loading indicator while the API script loads.
  3. Cleanup: If your component unmounts during a test, handle gracefully.
  4. Mobile Considerations: Speed tests use significant bandwidth. Consider warning users on mobile data.

TypeScript

For TypeScript projects, declare the SomApi global in src/types/speedofme.d.ts:

interface SpeedTestResult {
    download: number;
    upload: number;
    latency: number;
    jitter: number;
    testServer?: string;
    ip_address?: string;
    hostname?: string;
}

interface SomApi {
    account: string;
    domainName: string;
    config: SomApiConfig;
    startTest: () => void;
    onTestCompleted: (result: SpeedTestResult) => void;
    onProgress: (progress: SpeedTestProgress) => void;
    onError: (error: SpeedTestError) => void;
}

declare global {
    interface Window {
        SomApi: SomApi;
    }
}

Links