Frameworks
React
React and Next.js
[Overview](../) · Framework Integrations
Use @iconical/presence/react to keep a Discord presence card updated automatically. Hooks manage subscriptions, cleanup, and shared connections for you.
Install
bun add @iconical/presenceYour React project must also have its usual React dependencies installed.
Show one user's presence
import { usePresence } from "@iconical/presence/react";
import { getPlayingActivities } from "@iconical/presence";
const USER_ID = "123456789012345678"; // Replace with an approved ID.
export function PresenceCard() {
const { data, loading, error, refresh } = usePresence({ userId: USER_ID });
if (loading) return <p>Connecting…</p>;
if (error) return <p>Presence unavailable</p>;
if (!data) return <p>No presence data</p>;
return (
<section>
<h2>{data.profile.displayName}</h2>
<p>{data.presence?.status ?? "Waiting for a Discord update"}</p>
{getPlayingActivities(data.presence).map((game, index) => (
<p key={game.id ?? `${game.name}-${index}`}>{game.name}</p>
))}
{data.spotify && <p>Listening to {data.spotify.song}</p>}
<button type="button" onClick={refresh}>Reconnect</button>
</section>
);
}The hook returns data: PresenceResult | null, loading, error, and refresh(). A service interruption or revocation clears stale data rather than leaving an outdated online indicator.
Next.js client boundary
React hooks using subscriptions must run in a component marked with "use client".
Next.js App Router
A hook using browser subscriptions belongs in a client component. Put "use client" at the top of the component file:
"use client";
import { usePresence } from "@iconical/presence/react";
export default function DiscordStatus() {
const { data, loading, error } = usePresence({
userId: "123456789012345678",
});
if (loading) return <span>Connecting…</span>;
if (error) return <span>Unavailable</span>;
return <span>{data?.presence?.status ?? "Waiting for update"}</span>;
}You can import this client component into a server-rendered page. For a one-time server request, use the core createPresenceClient().getPresence() instead of a live hook.
Hook options
| Option | Purpose |
|---|---|
userId | Required numeric Discord ID |
enabled | Set false to disable the subscription |
transport | auto (default), sse, or poll |
intervalMs | Polling interval, minimum 5 seconds, default 15 seconds |
Use refresh() to restart the subscription; you do not need to manually call an unsubscribe function from the React hook.
Display multiple users
import { usePresences } from "@iconical/presence/react";
function TeamPresence() {
const { data, loading } = usePresences({
userIds: ["123456789012345678", "222222222222222222"],
});
if (loading) return <p>Loading team…</p>;
return (
<ul>
{Object.entries(data?.presences ?? {}).map(([id, member]) => (
<li key={id}>{member.profile.displayName}: {member.presence?.status ?? "Pending"}</li>
))}
</ul>
);
}Only approved users appear in the result. See Multi-user for limits and React widgets for ready-made cards.
Was this page helpful?