This example demonstrates how to integrate the SpeedOf.Me speed test API with React.
Open index.html in your browser to see a working example using CDN builds of React and Babel.
The index.html file shows how to use React with CDN builds. This is great for demos but not recommended for production.
npm create vite@latest my-speedtest -- --template react
cd my-speedtest
index.html:
<script src="https://speedof.me/api/api.js"></script>
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 };
}
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>
);
}
// 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;
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)
}
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
}
The onError callback receives an error object:
{
code: 1001,
message: 'Invalid API key'
}
Common error codes:
1001: Invalid account/API key1002: Domain mismatchFor 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;
}
}