# How do I fix these issues?

**URL:** <https://discuss.dev.twitch.com/t/how-do-i-fix-these-issues/64102>\
**Category:** Extensions\
**Created:** [July 31, 2025, 11:05pm UTC](https://discuss.dev.twitch.com/t/how-do-i-fix-these-issues/64102 "2025-07-31T23:05:34Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathan\_Jaffe](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/nathan_jaffe/32/30955_2.png) [@Nathan\_Jaffe](https://discuss.dev.twitch.com/u/Nathan_Jaffe)\
**Post date:** [July 31, 2025, 11:05pm UTC](https://discuss.dev.twitch.com/t/how-do-i-fix-these-issues/64102/1 "2025-07-31T23:05:34Z")

</div>

![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/d/c/dc47f18204daf3e7b024f9986c3d4c14c0a90743.png)  
Im using Cloudafre workers to talk to my Frontend but im hitting the wall. I added CORS headers in my workers js but nothing works!

this is my StreamersConfigTab.tsx:

```auto
import { useState, useEffect } from 'react';
import AppStatus from '../../components/AppStatus';
import { getStreamerStats } from '../../api/getStreamerStats';

type StreamerStats = {
    twitchUserId: string;
    challengesProposed: number;
    challengesCompleted: number;
    challengesFailed: number;
    totalBitsSpent: number;
    lastUpdated: string;
};

type ConfigStatCardProps = {
    label: string;
    value: number | string;
    loading: boolean;
};

function ConfigStatCard({ label, value, loading }: ConfigStatCardProps) {
    return (
        <div className="config-stat-card">
            <span className="config-stat-label">{label}</span>
            {loading ? (
                <div className="skeleton-item skeleton-config-value"></div>
            ) : (
                <span className="config-stat-value">
                    {typeof value === 'number' ? value.toLocaleString() : value}
                </span>
            )}
        </div>
    );
}

export default function StreamerConfigTab() {
    const [broadcasterId, setBroadcasterId] = useState<string | null>(null);
    const [authorized, setAuthorized] = useState(false);
    const [stats, setStats] = useState<StreamerStats | null>(null);
    const [status, setStatus] = useState<'checking' | 'connected' | 'disconnected'>('checking');
    const [riotId, setRiotId] = useState<string | null>(null);

    // ✅ Wait for Twitch.onAuthorized
    useEffect(() => {
        if (window.Twitch?.ext) {
            window.Twitch.ext.onAuthorized(auth => {
                setBroadcasterId(auth.channelId);
                setAuthorized(true);
            });
        } else {
            console.error('Twitch Helper not found.');
        }
    }, []);

    // 🔒 Gate rendering
    if (!authorized || !broadcasterId) {
        return <div className="config-container">Loading Twitch config...</div>;
    }

    // 📊 Fetch stats every 30s
    useEffect(() => {
        let mounted = true;

        const fetchStats = async () => {
            try {
                const data = await getStreamerStats(broadcasterId);
                if (mounted) setStats(data);
            } catch (e) {
                console.error(e);
            }
        };

        fetchStats();
        const id = setInterval(fetchStats, 30_000);
        return () => {
            mounted = false;
            clearInterval(id);
        };
    }, [broadcasterId]);

    // 🔌 Check PC App connection every 5s
    useEffect(() => {
        let mounted = true;

        const checkConn = async () => {
            try {
                const res = await fetch(`/status/connection?twitchUserId=${broadcasterId}`);
                const json = await res.json();
                if (mounted) setStatus(json.connected ? 'connected' : 'disconnected');
            } catch {
                if (mounted) setStatus('disconnected');
            }
        };

        checkConn();
        const id = setInterval(checkConn, 5_000);
        return () => {
            mounted = false;
            clearInterval(id);
        };
    }, [broadcasterId]);

    // 🧠 Fetch Riot ID if connected
    useEffect(() => {
        if (status !== 'connected') {
            setRiotId(null);
            return;
        }

        let mounted = true;

        const fetchRiot = async () => {
            try {
                const active = await fetch(`/match/active?twitchUserId=${broadcasterId}`).then(r => r.json());
                if (!mounted) return;

                if (active.sessionId) {
                    const detail = await fetch(`/match/${active.sessionId}/status`).then(r => r.json());
                    if (mounted) setRiotId(detail.riotId);
                } else {
                    setRiotId(null);
                }
            } catch {
                if (mounted) setRiotId(null);
            }
        };

        fetchRiot();
        return () => {
            mounted = false;
        };
    }, [status, broadcasterId]);

    return (
        <div className="config-container">
            <h1>Streamer Configuration</h1>

            <div className="config-section">
                <h2 className="config-section-title">Connection Status</h2>
                <div className="config-grid">
                    <div className="config-stat-card">
                        <span className="config-stat-label">PC Application</span>
                        <AppStatus status={status} />
                    </div>
                    {status === 'connected' && (
                        <div className="config-stat-card">
                            <span className="config-stat-label">Connected Riot ID</span>
                            <span className="config-stat-value">{riotId || 'N/A'}</span>
                        </div>
                    )}
                </div>
            </div>

            <div className="config-section">
                <h2 className="config-section-title">Lifetime Stats</h2>
                <div className="config-grid">
                    <ConfigStatCard label="Challenges Proposed" value={stats?.challengesProposed ?? 0} loading={!stats} />
                    <ConfigStatCard label="Challenges Completed" value={stats?.challengesCompleted ?? 0} loading={!stats} />
                    <ConfigStatCard label="Challenges Failed" value={stats?.challengesFailed ?? 0} loading={!stats} />
                    <ConfigStatCard label="Bits Spent" value={stats?.totalBitsSpent ?? 0} loading={!stats} />
                </div>
                {stats && (
                    <p className="last-updated-text">
                        Last updated: {new Date(stats.lastUpdated).toLocaleString()}
                    </p>
                )}
            </div>
        </div>
    );
}

```

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [August 1, 2025, 9:55am UTC](https://discuss.dev.twitch.com/t/how-do-i-fix-these-issues/64102/2 "2025-08-01T09:55:58Z")

</div>

Are you actually calling `api.sprig.com` or cloudflare workers?

I don’t think `api.sprig.com` is anything to do with your extension.

Since you say you are using cloudflare workers.  
So this error is unrelated to your extension, especially as the parent “caller” is `dashboard.twitch.tv` and not your extension.

I don’t see anything obviouslly wrong in your provided front end code, so likely an api fault with your API?
