Embedded App SDK
Connect your activity to Discord
The Embedded App SDK (@discord/embedded-app-sdk) connects your activity to Discord. Since activities run inside Discord's embedded frame, this SDK provides the bridge between your web app and Discord's features — handling authorization, authentication, and access to Discord APIs.
Setup
The SDK is included in activity templates. DiscordContextProvider wraps the app in src/app/App.tsx:
This code is already in your project if you used the activity template.
import { DiscordContextProvider } from '../hooks/useDiscordSdk'
import { Activity } from './Activity'
export default function App() {
return (
<DiscordContextProvider authenticate scope={['identify', 'guilds']}>
<Activity />
</DiscordContextProvider>
)
}import { DiscordContextProvider } from '../hooks/useDiscordSdk'
import { Activity } from './Activity'
export default function App() {
return (
<DiscordContextProvider authenticate scope={['identify', 'guilds']}>
<Activity />
</DiscordContextProvider>
)
}This provider initializes the SDK, handles the OAuth2 flow, and makes the SDK instance available to child components.
DiscordContextProvider
| Prop | Type | Description |
|---|---|---|
authenticate | boolean | Prompt users to authenticate on load |
scope | string[] | OAuth2 scopes to request |
loadingScreen | ReactNode | Component shown during authentication |
When authenticate is set, the provider automatically runs the full authorization and authentication flow on mount.
useDiscordSdk Hook
Access SDK state and user data from any component:
import { useDiscordSdk } from '../hooks/useDiscordSdk'
export function Activity() {
const { authenticated, session, status } = useDiscordSdk()
if (!authenticated) {
return <div>Connecting...</div>
}
return <div>Welcome, {session?.user.username}</div>
}import { useDiscordSdk } from '../hooks/useDiscordSdk'
export function Activity() {
const { authenticated, session, status } = useDiscordSdk()
if (!authenticated) {
return <div>Connecting...</div>
}
return <div>Welcome, {session?.user.username}</div>
}| Field | Type | Description |
|---|---|---|
accessToken | string | null | OAuth2 access token |
authenticated | boolean | Whether authentication succeeded |
discordSdk | DiscordSDK | SDK instance |
error | string | null | Error message if authentication failed |
session | DiscordSession | null | Authenticated user session |
status | string | Current status: pending, loading, authenticating, ready, error |
Status progresses: pending -> loading -> authenticating -> ready (or error if something goes wrong at any step).
A Discord Activity running in the embedded panel showing 'Welcome, username', demonstrating the SDK has authenticated the user and retrieved session data
SDK Instance
The discordSdk object provides access to Discord commands and events.
| Command | Description |
|---|---|
ready() | Signal the SDK is ready |
commands.authorize() | Request OAuth2 authorization |
commands.authenticate() | Authenticate with an access token |
commands.getChannel() | Get current channel info |
commands.getInstanceConnectedParticipants() | List connected participants |
subscribe() | Subscribe to SDK events |
Example using the SDK instance directly:
const { discordSdk } = useDiscordSdk()
const channel = await discordSdk.commands.getChannel({ channel_id: discordSdk.channelId })const { discordSdk } = useDiscordSdk()
const channel = await discordSdk.commands.getChannel({ channel_id: discordSdk.channelId })Mock Mode
The template auto-detects whether the app runs inside Discord by checking for a frame_id query parameter — a value Discord adds to the URL when loading your app inside its embedded frame. Outside Discord, it uses DiscordSDKMock for local development.
Mock mode generates random values for user, guild, and channel IDs, stored in session storage so they persist across refreshes within the same tab.
Override mock values via query parameters:
| Parameter | Description |
|---|---|
user_id | Override the mock user ID |
guild_id | Override the mock guild ID |
channel_id | Override the mock channel ID |
A browser window showing the activity running at localhost outside of Discord, operating in mock mode with randomly generated user data
Vanilla Projects
For non-React projects, import the SDK directly. Call ready() and handle authorization and authentication manually:
import { DiscordSDK } from '@discord/embedded-app-sdk'
const discordSdk = new DiscordSDK(import.meta.env.VITE_DISCORD_CLIENT_ID)
await discordSdk.ready()import { DiscordSDK } from '@discord/embedded-app-sdk'
const discordSdk = new DiscordSDK(import.meta.env.VITE_DISCORD_CLIENT_ID)
await discordSdk.ready()See the Authentication page for the full vanilla authorization flow, including the code-for-token exchange.
