Adding Live Discord Status to Your Website

Because static "available" badges are as outdated as using Internet Explorer… and your visitors deserve to know if you're actually online or just pretending to be productive.

Dev Adnani
July 12, 2025
4 min read
DiscordWeb DevelopmentAPI IntegrationReal-Time

1. Why Show Your Discord Status? 🎮

Think of those "Currently offline" messages that never update—about as useful as a chocolate teapot. A live Discord status tells visitors when you're actually around, what you're playing, or if you're vibing to Spotify. It's like having a digital pulse on your website.


2. Ingredient List 🛠️

SpicePurpose
Lanyard APIDiscord status without the OAuth headache
React / Next.jsThe sauté pan where everything simmers
Tailwind CSSMaking it look spicy, not basic
TypeScriptBecause runtime errors are no fun
Discord Dev ModeTo grab your user ID like a pro

3. Getting Your Discord User ID (2 min prep)

  1. Open Discord → Settings → Advanced → Enable Developer Mode
  2. Right-click your username anywhere → Copy ID
  3. Save that 18-digit number — it's your golden ticket 🎫

4. Testing the Lanyard API 🚀

Test it first in your browser:

PLAIN
<https://api.lanyard.rest/v1/users/YOUR_DISCORD_ID>

Or curl it like a boss:

PLAIN
curl <https://api.lanyard.rest/v1/users/1017791954752376893>

5. Building the Discord Status Component 🎨

TYPESCRIPT
"use client";
import React, { useState, useEffect } from "react";

interface DiscordStatus {
  discord_status: "online" | "idle" | "dnd" | "offline";
  discord_user: {
    username: string;
    discriminator: string;
    avatar: string;
    id: string;
  };
  activities: Array<{
    name: string;
    type: number;
    state?: string;
    details?: string;
  }>;
  listening_to_spotify: boolean;
  spotify?: {
    song: string;
    artist: string;
    album_art_url: string;
  };
}

const statusColors = {
  online: "text-green-500",
  idle: "text-yellow-500",
  dnd: "text-red-500",
  offline: "text-gray-500",
};

const DiscordLogo = ({ className }: { className?: string }) => (
  <svg className={className} viewBox="0 0 24 24" fill="currentColor">...</svg>
);

export function DiscordStatus({ userId }: { userId: string }) {
  const [status, setStatus] = useState<DiscordStatus | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchStatus = async () => {
      try {
        const response = await fetch(`https://api.lanyard.rest/v1/users/${userId}`);
        const data = await response.json();
        setStatus(data.data);
      } catch (error) {
        console.error("Failed to fetch Discord status:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchStatus();
  }, [userId]);

  if (loading) return <div>Loading...</div>;
  if (!status) return null;

  const currentGame = status.activities.find(
    (activity) => activity.type === 0 && activity.name !== "Spotify"
  );

  return (
    <div onClick={() => window.open('<https://discord.gg/your-server>', '_blank')}>
      <DiscordLogo className={`w-8 h-8 ${statusColors[status.discord_status]}`} />
      <span>{status.discord_user.username}</span>
      <span>
        {status.discord_status === 'online' ? 'Online' :
         status.discord_status === 'idle' ? 'Away' :
         status.discord_status === 'dnd' ? 'Do Not Disturb' : 'Offline'}
      </span>
      {currentGame && <div>🎮 Playing {currentGame.name}</div>}
      {status.listening_to_spotify && status.spotify && (
        <div>🎵 {status.spotify.song} by {status.spotify.artist}</div>
      )}
    </div>
  );
}

6. Status Flow 🔄

MERMAID
graph LR
WEBSITE[Your Website] -->|Fetch Once| LANYARD[Lanyard API]
LANYARD -->|Real-time Data| DISCORD[Discord Status]
DISCORD -->|Activities| GAMES[Gaming Activity]
DISCORD -->|Music| SPOTIFY[Spotify Status]
GAMES -->|Display| UI[Status Component]
SPOTIFY -->|Display| UI

7. Performance Tips 🔋

StrategyWhen to UseBattery Impact
Fetch once on loadPersonal portfolio⚡ Minimal
30-second intervalsCommunity pages⚡⚡ Moderate
WebSocket connectionDashboards, real-time⚡⚡⚡ Heavy

My pick: Fetch once on page load. Keep it simple for most use cases.


8. Cache + Graceful Degradation

PLAIN
const CACHE_KEY = 'discord-status-cache';
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

const getCachedStatus = () => {
  const cached = localStorage.getItem(CACHE_KEY);
  if (cached) {
    const { data, timestamp } = JSON.parse(cached);
    if (Date.now() - timestamp < CACHE_DURATION) {
      return data;
    }
  }
  return null;
};

if (!status) {
  return (
    <a href="<https://discord.gg/your-server>" target="_blank">
      <DiscordLogo className="w-6 h-6 text-gray-400" />
      <span>Join Discord</span>
    </a>
  );
}

9. Deployment Gotchas 🚨

  • ❌ Using your Discord ID as a secret (it's not)
  • ❌ Over-fetching (once per page load is fine)
  • ❌ Skipping loading state (blank UIs = bad UX)

10. Conclusion 🔥

With Lanyard and a little React/TypeScript magic, you can show live presence on your site in just a few lines of code. Visitors get to see if you’re truly around, and you get to flex your dev skills.

Clone, remix, and ship it. And yeah, let's make static status badges extinct. 🦕


📚 Further Reading

Feeling inspired? Drop a comment or ping me on Discord — I’m probably online anyway! 😄

Dev Adnani

Software Engineer & Web3 Enthusiast