Proxy
Handle Discord's Content Security Policy in your activity
The Discord Proxy enforces a strict Content Security Policy (CSP) — a browser security mechanism that controls which URLs your app can load resources from — on all activities. Understanding these rules is essential for loading external resources.
Content Security Policy
CSP restricts which resources an activity can load. Discord only allows requests to your application's origin and mapped domains. External URLs, inline scripts, and unauthorized domains are blocked.
Proxy Rules
| Rule | Description |
|---|---|
| No external URLs | Direct requests to external domains are blocked |
| HTTPS only | All requests must use HTTPS |
/.proxy prefix | Internal requests use the /.proxy path prefix |
| Per-app CSP | Each application has a unique CSP directive |
Browser DevTools console showing Content Security Policy violation errors when an activity tries to load resources from an unmapped external domain
@robojs/patch
@robojs/patch provides automatic URL patching via a Vite plugin. It is pre-installed in all activity templates and requires zero configuration.
import { DiscordProxy } from '@robojs/patch'
import react from '@vitejs/plugin-react-swc'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [react(), DiscordProxy.Vite()]
})import { DiscordProxy } from '@robojs/patch'
import react from '@vitejs/plugin-react-swc'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [react(), DiscordProxy.Vite()]
})URL Mapping
Configure URL mappings in the Discord Developer Portal under your application's URL Mappings section. Each mapping associates a path prefix with an external origin.
| Prefix | Target |
|---|---|
/google-fonts | https://fonts.googleapis.com |
/cdn | https://cdn.example.com |
Use mapped paths in your code:
fetch('/google-fonts/css2?family=Inter')fetch('/google-fonts/css2?family=Inter')Discord Developer Portal URL Mappings section showing multiple prefix-to-target mappings for external services like Google Fonts and a CDN
URL Patching
Most developers don't need this — DiscordProxy.Vite() handles URL rewriting automatically. This section is for cases where third-party libraries use hardcoded domains that the Vite plugin can't reach.
patchUrlMappings() from @discord/embedded-app-sdk rewrites URLs in third-party libraries that have hardcoded domains:
import { patchUrlMappings } from '@discord/embedded-app-sdk'
patchUrlMappings([{ prefix: '/google-fonts', target: 'fonts.googleapis.com' }])import { patchUrlMappings } from '@discord/embedded-app-sdk'
patchUrlMappings([{ prefix: '/google-fonts', target: 'fonts.googleapis.com' }])Custom Proxy Server
For reaching services that Discord's URL Mappings cannot handle (such as specific ports, unsupported protocols, or dynamic URLs), create a custom proxy endpoint:
import type { RoboRequest } from '@robojs/server'
export default async (req: RoboRequest) => {
const url = req.query.url as string
return fetch(url)
}export default async (req) => {
const url = req.query.url
return fetch(url)
}Validate and sanitize the target URL to prevent URL injection and SSRF attacks.
Network Limitations
| Protocol | Supported |
|---|---|
| HTTPS | Yes |
| WebSocket | Yes |
| DASH / HLS | Yes |
| WebRTC | No |
| WebTransport | No |
Security
The proxy hides user IP addresses. Since the SDK runs in the user's browser, a malicious user could modify the data it reports. Do not trust data from the Embedded App SDK as authoritative. Always validate server-side using the OAuth2 access token from authentication.
