If you were previously using activity-iframe-sdk, this guide is for you. Think of @discord/embedded-app-sdk as the next version of activity-iframe-sdk with a few breaking changes. This document is aimed to help developers migrate their activity code from activity-iframe-sdk v2 to @discord/embedded-app-sdk v1.0.0 and beyond. If you are upgrading from activity-iframe-sdk v1, please first reference this document
Here's the high level list of changes
- New SDK Name
- Typescript support for subscribe and unsubscribe
- initializeNetworkShims is different
- Removing unused commands, events, and types
We've renamed the SDK to align with the long-term vision for Discord apps. If you're embedding an app inside of Discord, this SDK has got you covered. The main use case today is for Discord apps which launch activities via iframes, however, as this name implies, this SDK could support use for Discord applications beyond just activities.
Previously, there were no typescript types provided when subscribing to events. Now, as soon as you provide an event name, typescript can help infer the shape of data returned by the callback, as well as additional subscribeArgs, when necessary.
Often, you may not want to describe the subscription callback inline. If you are using typescript, you can define the event shape outside of the callback, using the generic type EventPayloadData. Check out this example where we subscribe to the SPEAKING_START event.
import {DiscordSDK, EventPayloadData} from '@discord/embedded-app-sdk';
// Initialize the SDK
const discordSdk = new DiscordSDK(CLIENT_ID);
// Retrieve the typescript type for the SPEAKING_START event
type SPEAKING_START_EVENT = EventPayloadData<'SPEAKING_START'>;
// Define the callback function that will fire whenever a SPEAKING_START event is captured
function handleStartTalking(event: SPEAKING_START_EVENT) {
console.log(`user ${event.user_id} started talking`);
}
// Subscribe to the SPEAKING_START event and pass appropriate
discordSdk.subscribe('SPEAKING_START', handleStartTalking, {channel_id: discordSdk.channelId});
If you're using initializeNetworkShims in your activity, you will need to migrate it to the new API patchUrlMappings. It's the same in spirit, but it has a few differences:
- We have renamed
initializeNetworkShimstopatchUrlMappings patchUrlMappingsis now exported as a utility separate from the SDK. This allows you to initialize shims as soon as possible, separate from SDK initializationpatchUrlMappingsnow includes new functionality that can update htmlsrcattributes to adjust to your url mappings.patchUrlMappingsnow includes a second argument where you can set specific configuration for each "shim". See usage in the example below
import {patchUrlMappings} from '@discord/embedded-app-sdk';
patchUrlMappings(
[
{
target: 'google.com',
prefix: '/google',
},
],
{
patchFetch: true, // Defaults to true
patchWebSocket: true, // Defaults to true
patchXhr: true, // Defaults to true
patchSrcAttributes: true, // Defaults to false (potentially compute expensive for your UI)
}
);
The original SDK included several events and commands which are either no longer relevant, unusable, or otherwise not something we want in the SDK.
The following were removed or modified:
- Removed Events
ACTIVITY_JOIN- If you are using this today, we encourage subscribing to the
ACTIVITY_INSTANCE_PARTICIPANTS_UPDATEevent instead
- If you are using this today, we encourage subscribing to the
ACTIVITY_SPECTATE- If you are using this today, we encourage subscribing to the
ACTIVITY_INSTANCE_PARTICIPANTS_UPDATEevent instead
- If you are using this today, we encourage subscribing to the
ACTIVITY_PIP_MODE_UPDATE- If you are using this today, we encourage subscribing to the
ACTIVITY_LAYOUT_MODE_UPDATEevent instead
- If you are using this today, we encourage subscribing to the
CAPTURE_SHORTCUT_CHANGEGUILD_STATUSGUILD_CREATECHANNEL_CREATEVOICE_CHANNEL_CREATENOTIFICATION_CREATEACTIVITY_JOIN_REQUESTVOICE_STATE_CREATEVOICE_STATE_DELETEVOICE_SETTINGS_UPDATEVOICE_CONNECTION_STATUS
- Removed Commands
getSelectedVoiceChannelWe recommend usinggetChannelinstead, where appropriate. If you need access to the current channel's id, it can be accessed immediately by the SDK, directly atdiscordSdk.channelIdsubscribeToLayoutModeUpdatesCompatandunsubscribeFromLayoutModeUpdatesCompat- If you are using these today, we encourage subscribing to the
ACTIVITY_LAYOUT_MODE_UPDATEevent instead
- If you are using these today, we encourage subscribing to the
setUserVoiceSettingssetVoiceSettingsgetVoiceSettingsstartPremiumPurchase
Each activity is implemented differently, but migrating to embedded-app-sdk from activity-iframe-sdk should be straightforward with the use of typescript. Here is a simple outline of how we expect the migration should occur.
- If you are upgrading from
activity-iframe-sdkv1, please review and implement the activity-iframe-sdk v2 migration guide before following these steps. - Upgrade by uninstalling the old package and installing the new.
npm uninstall @discord-external/activity-iframe-sdknpm install @discord/embedded-app-sdk
- Remove any code related to installing a private github package. This will most likely look like removing a
.npmrcfile or other references tonpm.pkg.github.com - Run typescript (
tsc) and observe errors. Most of the errors will be related to usage ofsubscribe, or usage of removed commands and events, as expected. - Fix typescript errors. We expect most of not all typescript errors will be related to
subscribe. The typeEventPayloadData<'YOUR_EVENT'>will be your biggest helper here. Remove usage of unsupported events and command, and migrate as necessary, per recommandations above - Perform a basic test of key functionality.
- Profit from having type safety and the latest SDK updates from here on out!
As a real example, our sdk-playground example application migrated to @discord/embedded-app-sdk 1.0.0 from @discord/activity-iframe-sdk. This is a summary of all the changes required.
Migrate subscribeToLayoutModeUpdatesCompat command to instead subscribe to the ACTIVITY_LAYOUT_MODE_UPDATE event
examples/sdk-playground/packages/client/src/pages/LayoutMode.tsx
- import {Common} from '@discord/activity-iframe-sdk';
+ import {Common, EventPayloadData} from '@discord/embedded-app-sdk';
- const handleLayoutModeUpdate = React.useCallback((update: {layout_mode: number}) => {
+ const handleLayoutModeUpdate = React.useCallback((update: EventPayloadData<'ACTIVITY_LAYOUT_MODE_UPDATE'>) => {
React.useEffect(() => {
- discordSdk.subscribeToLayoutModeUpdatesCompat(handleLayoutModeUpdate);
+ discordSdk.subscribe('ACTIVITY_LAYOUT_MODE_UPDATE', handleLayoutModeUpdate);
return () => {
- discordSdk.unsubscribeFromLayoutModeUpdatesCompat(handleLayoutModeUpdate);
+ discordSdk.unsubscribe('ACTIVITY_LAYOUT_MODE_UPDATE', handleLayoutModeUpdate);
examples/sdk-playground/packages/client/src/pages/Instance.tsx
- import {Events, Types} from '@discord/activity-iframe-sdk';
+ import {Events, EventPayloadData} from '@discord/embedded-app-sdk';
- type UpdateEvent = Types.GetActivityInstanceConnectedParticipantsResponse;
+ type UpdateEvent = EventPayloadData<'ACTIVITY_INSTANCE_PARTICIPANTS_UPDATE'>;
- import {DiscordSDK, DiscordSDKMock, IDiscordSDK} from '@discord/embedded-app-sdk';
+ import {DiscordSDK, DiscordSDKMock, IDiscordSDK, patchUrlMappings} from '@discord/embedded-app-sdk';
- discordSdk.initializeNetworkShims(mappings);
+ patchUrlMappings(mappings);