Discord Activity SPA Implementation Guide

Overview

This document describes the isolated Discord Activity implementation for AeThex. The Activity is now a true Single-Page Application (SPA) that runs entirely within Discord's iframe and complies with Discord's Activity requirements.

Architecture

Isolated SPA Pattern (Option A)

The Activity is completely isolated from the main AeThex app:

Discord Client

    └─→ Activity Iframe (SPA)
        ├─ Discord SDK initialization
        ├─ OAuth flow via postMessage
        ├─ User profile display
        ├─ Realm/Arm information
        └─ Quick action buttons (open in new window)

            └─→ Main App (https://aethex.dev) opens in new tab

Key Changes from Previous Implementation

1. Removed Router Navigation

  • Before: Activity used useNavigate() to redirect within React Router

  • After: Activity is completely self-contained, no internal navigation

  • Before: <a href="/creators"> navigated within the iframe

  • After: <button onClick={() => window.open(url, "_blank")}> opens the main app in a new tab

  • This allows users to see full features without breaking Activity isolation

3. Simplified Manifest

  • Before: Manifest referenced multiple domains including aethex.dev

  • After: Manifest ONLY references Discord proxy domain (578971245454950421.discordsays.com)

  • This ensures Activity is properly sandboxed through Discord's proxy

File Changes

code/client/pages/Activity.tsx

Removed:

Added:

Link Changes:

code/public/discord-manifest.json

Before:

After:

Discord Compliance

✅ What This Implementation Does Right

  1. True SPA - Activity never navigates away from itself

  2. Proper Iframe Isolation - No breaking out of Discord's sandbox

  3. PostMessage Protocol - Uses Discord SDK which handles postMessage communication

  4. Proxy Domain Only - Manifest restricted to Discord proxy domain

  5. No External Navigation - Links open in new windows, don't break the Activity

⚠️ Important Limitations

  1. Activity is Read-Only for Display - Can't directly modify the main app from Activity

  2. No Shared Navigation - Activity can't control main app routing

  3. Data Sync Limitation - Activity shows cached/API data, not real-time main app state

  4. URL Mappings Required - Any external resources accessed by Activity need URL mappings in manifest

Testing the Activity

Prerequisites

  1. Have a Discord server where you're an admin

  2. Have registered the AeThex application on Discord Developer Portal

  3. Have installed the AeThex bot in your test server

Local Testing

  1. Start the dev server:

  2. Open Discord and find an Activity that can be launched

    • Right-click on a voice channel

    • Select "Launch Activity"

    • Look for "AeThex Activity"

  3. Expected behavior:

    • Activity loads without errors

    • User profile displays correctly

    • Buttons open links in new tabs (not navigate within Activity)

    • Discord commands still work (/profile, /set-realm, etc.)

Deployment Testing

  1. After deploying to production:

  2. Update Discord Developer Portal with production URL

  3. Test in Discord with production URL

Future Enhancements

Expanding Activity Features Without Breaking SPA

If you want to add more features to the Activity without breaking isolation, use the Nested Messages Pattern:

URL Mappings for External Resources

If Activity needs to access external APIs, update the manifest:

Then in code, use relative paths:

Troubleshooting

Activity Won't Load

  1. Check browser console for [Discord Activity] logs

  2. Verify frame_id in URL - should be present in Discord iframe

  3. Check CORS settings - Activity may be blocked by CORS policies

  4. Verify manifest - Make sure manifest.json is served correctly

  1. Ensure target="_blank" or window.open() - Regular navigation breaks Activity

  2. Check URL construction - Verify full URL is correct

  3. Test in separate browser tab - Verify links work outside Activity

User Profile Not Loading

  1. Check /api/discord/activity-auth endpoint

  2. Verify Supabase integration - User data must exist in database

  3. Check token expiry - OAuth token may have expired

Configuration Checklist

Last updated