How to Fix Stuck Ready Event in Discord Embedded App SDK
If you've been following Discord's Building Your First Activity tutorial, you may have encountered an issue where the Embedded App SDK gets stuck on the READY
event. This issue can be caused by a few different things, but the most common cause is Vite's hot module reloading (HMR) feature.
We've seen this issue pop up in a few different places, so we wanted to provide a quick guide on how to fix it. This post will explain it in more detail and suggest ways around it.
TLDR; Quick Fix
If you're in a hurry, the quickest way to fix this without disabling HMR is to make sure you're creating only one instance of the DiscordSDK
close to the root of your app. Check out this template to see how it's done.
You can also create a new Discord Activity project with the fix already included by running this in your terminal:
npx create-robo <projectName> -k activity
What's Happening?
When you're developing a Discord Activity with Vite, the hot module reloading feature can cause the SDK to be re-created multiple times. This is because Vite reloads the module when you make changes, which can cause the DiscordSDK
to be reinitialized.
Unfortunately, discordSdk.ready()
gets stuck on the READY
event because Discord sends the payload once per instance. That means your activity will be left waiting for the READY
event to fire, but it never will until you restart it.
Starting Fresh with a Fix
To fix this issue, you need to ensure that you're only creating one instance of the DiscordSDK
close to the root of your app. This way, the SDK won't be re-initialized every time you make changes, thus you won't need to await discordSdk.ready()
more than once.
The easiest and fastest way to prevent this is to make sure you start from a template that already has this fix in place. You can clone this template or create a new project with the fix included by running:
npx create-robo <projectName> -k activity
This will create a new Discord Activity project with the fix already in place, so you won't have to worry about this issue. Check out our guide for more info!
➞ ✨ Guide: Creating a Discord Activity in seconds with Robo.js
Fixing Your Existing Project
If you're already working on a project and don't want to start over, you can fix this issue by ensuring that you're only creating one instance of the DiscordSDK
close to the root of your app. For example, in a React app, you can use a Context to manage the SDK instance.
Here's a simplified example:
import { DiscordSDK, DiscordSDKMock } from '@discord/embedded-app-sdk'
import { createContext, useContext } from 'react'
export const discordSdk = new DiscordSDK(import.meta.env.VITE_DISCORD_CLIENT_ID)
const DiscordContext = createContext({ discordSdk })
export function DiscordContextProvider(props) {
const { children } = props
const setupResult = useDiscordSdkSetup()
return <DiscordContext.Provider value={setupResult}>{children}</DiscordContext.Provider>
}
export function useDiscordSdk() {
return useContext(DiscordContext)
}
function useDiscordSdkSetup() {
// Your setup logic here (e.g., discordSdk.ready() in a useEffect)
return { discordSdk }
}
Then apply the DiscordContextProvider
at the root of your app:
import { DiscordContextProvider } from '../hooks/useDiscordSdk'
import { Activity } from './Activity'
import './App.css'
export default function App() {
return (
<DiscordContextProvider>
<Activity />
</DiscordContextProvider>
)
}
This way, Vite won't re-initialize the DiscordSDK
every time you make changes, and you won't get stuck on the READY
event. It works like so:
- The
DiscordSDK
is created once and passed down through the context. - The SDK is initialized in the context provider.
- Components can access the SDK through the custom
useDiscordSdk
hook. - The same SDK instance will be re-used, as long as you don't edit the
useDiscordSdk
file.
Conclusion
React's Context is a great way to manage global state in your app, and it's perfect for managing the DiscordSDK
instance. By ensuring that you only create one instance of the SDK close to the root of your app, you can prevent the READY
event from getting stuck and avoid the need to restart your activity every time you make changes.
We highly recommend using create-robo
to create a Discord Activity project. These templates are designed to help you get started quickly and avoid common issues like this one. What's more, they come with a lot of other features and tools to help you build your activity faster and more efficiently, such as Multiplayer Support, TypeScript, Easy Hosting, Streamlined Tunnels, Built-in Database, Plugin System, and so much more!
Don't forget to join our Discord server to chat with other developers, ask questions, and share your projects. We're here to help you build amazing apps with Robo.js! 🚀
➞ 🚀 Community: Join our Discord Server
Our very own Robo, Sage, is there to answer any questions about Robo.js, Discord.js, and more