Joker Vibes • Rot/Schwarz • Stream Design
Die Fanpage für Dennis Diez
Eine moderne Twitch Landingpage mit Live-Status, eingebettetem Stream, Twitch-Chat und einer großen Seitenvorschau im Design deines Logos. Die Farben sind auf Rot, Schwarz und Weiß abgestimmt.
Live Bereich
Der Stream läuft direkt auf deiner Seite. Rechts daneben siehst du Live-Status, Zuschauerzahl und Streamtitel.
Chat + Seitenvorschau
Links siehst du eine große Vorschau der Fanpage. Rechts ist der eingebettete Twitch-Chat für die Community.
Joker Style
Twitch Embed
Live Status
Follower Counter
Community Chat
Countdown + Letzter Stream
Ein Live-Countdown bis zum nächsten Stream und darunter die letzten Stream-Highlights im gleichen Joker-Style.
Nächster Stream
Freitag • 20:00 Uhr
00
Tage
00
Stunden
00
Minuten
00
Sekunden
Letzte Streams
Community Abend mit Dennis
Vor 1 Tag
Joker Night und Reactions
Vor 3 Tagen
Late Night Talk mit Chat
Vor 6 Tagen
Twitch API Setup
Trage deinen Kanalnamen, deine Domain und deinen Backend-Endpunkt ein. Dann zeigt die Seite echten Live-Status an.
const config = {
channel: 'dennisdiez',
parentDomain: window.location.hostname || 'localhost',
statusEndpoint: '/api/twitch-status?channel=dennisdiez',
schedule: {
label: 'Freitag • 20:00 Uhr',
nextStreamISO: '2026-04-10T20:00:00'
}
};
Beispiel JSON aus deinem Backend:
{
"live": true,
"viewer_count": 128,
"follower_count": 5421,
"game_name": "Just Chatting",
"title": "Heute live mit Community"
}
Node.js Beispiel (Express):
import express from 'express';
const app = express();
const TWITCH_CLIENT_ID = 'DEINE_CLIENT_ID';
const TWITCH_CLIENT_SECRET = 'DEIN_CLIENT_SECRET';
const TWITCH_CHANNEL_LOGIN = 'dennisdiez';
let accessToken = null;
let accessTokenExpiresAt = 0;
async function getAppToken() {
if (accessToken && Date.now() < accessTokenExpiresAt) return accessToken;
const response = await fetch('https://id.twitch.tv/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
client_id: TWITCH_CLIENT_ID,
client_secret: TWITCH_CLIENT_SECRET,
grant_type: 'client_credentials'
})
});
const data = await response.json();
accessToken = data.access_token;
accessTokenExpiresAt = Date.now() + ((data.expires_in - 60) * 1000);
return accessToken;
}
async function twitchGet(url) {
const token = await getAppToken();
const response = await fetch(url, {
headers: {
'Client-Id': TWITCH_CLIENT_ID,
'Authorization': `Bearer ${token}`
}
});
return response.json();
}
app.get('/api/twitch-status', async (req, res) => {
try {
const userData = await twitchGet(`https://api.twitch.tv/helix/users?login=${TWITCH_CHANNEL_LOGIN}`);
const user = userData.data?.[0];
if (!user) return res.status(404).json({ error: 'Channel not found' });
const streamData = await twitchGet(`https://api.twitch.tv/helix/streams?user_id=${user.id}`);
const channelData = await twitchGet(`https://api.twitch.tv/helix/channels?broadcaster_id=${user.id}`);
const followersData = await twitchGet(`https://api.twitch.tv/helix/channels/followers?broadcaster_id=${user.id}`);
const liveStream = streamData.data?.[0];
const channel = channelData.data?.[0];
res.json({
live: Boolean(liveStream),
viewer_count: liveStream?.viewer_count ?? 0,
follower_count: followersData.total ?? 0,
game_name: channel?.game_name || 'Offline',
title: channel?.title || 'Kein Titel vorhanden'
});
} catch (error) {
res.status(500).json({ error: 'Twitch API Fehler' });
}
});
app.listen(3000, () => {
console.log('Server läuft auf http://localhost:3000');
});