Racelink
Documentation · Data from the internet

// Documentation · Avancé

Data from the internet

A forecast, a league’s standings, a stream’s alerts: an overlay may reach the hosts it names, once the player agrees.

Ce guide n’existe pour l’instant qu’en anglais.

List the hosts in the manifest

An overlay reaches only Racelink until its manifest names hosts and the player allows them (Security):

racelink.overlay.json
"permissions": { "internet": ["api.example.com", "*.cdn.example.com"] }
  • Up to 20 hosts. *.example.com covers every subdomain.
  • Host names only: no scheme, port, path, IP address or local name.
  • Over HTTPS and WSS: fetch, WebSocket, and images, media and fonts from those hosts.
  • Scripts still load only from your package, whatever the hosts.

The player decides

The player sees the hosts when they add the overlay and may refuse. They may also change their mind later; Racelink then reloads the overlay so it starts with the new rules. A new version that adds a host asks again, and the new host stays closed until the player agrees.

Work without the internet too

overlay.permissions.internet says whether the hosts are open. Check it before you fetch, and draw something useful when they are not:

src/forecast.ts
const loadForecast = async (): Promise<void> => {
if (!overlay.permissions.internet) {
forecast.textContent = 'Forecast is off';
return;
}
try {
const response = await fetch('https://api.example.com/forecast?track=' + trackId);
if (!response.ok) throw new Error(String(response.status));
showForecast(await response.json());
} catch {
forecast.textContent = 'No forecast';
}
};
src/Forecast.tsx
export function Forecast({ overlay, trackId }: ForecastProps) {
const [data, setData] = useState<ForecastData | null>(null);
const allowed = overlay.permissions.internet;
useEffect(() => {
if (!allowed) return;
const controller = new AbortController();
fetch('https://api.example.com/forecast?track=' + trackId, { signal: controller.signal })
.then((response) => (response.ok ? response.json() : null))
.then(setData)
.catch(() => setData(null));
return () => controller.abort();
}, [allowed, trackId]);
if (!allowed) return <p className="forecast">Forecast is off</p>;
return data ? <ForecastView data={data} /> : <p className="forecast">No forecast</p>;
}

During development the page comes from your own dev server, so the browser applies your server’s rules, not the overlay’s: a host missing from the manifest works for you and fails for players. Keep the list in the manifest complete.