Add the widget in minutes (Basic) or enable Secure mode for maximum protection.
This guide is for website owners who want to add the Dreamcode chat widget to their site. You can choose between Basic mode (fast setup) and Secure mode (recommended — protects against origin spoofing and local /etc/hosts tricks).
Paste this snippet before </body> on your website:
<script src="https://dreamcode.am/widget/YOUR_API_TOKEN.js" async></script>
After deployment, open your website and send a test message. If you get 403 Widget is not authorized for this domain, your domain is not whitelisted in the Dreamcode Client settings.
Secure mode prevents unauthorized use of the widget even if someone tries to spoof your domain locally. It requires a small backend endpoint on your website.
Step A — enable Secure mode in Dreamcode
Step B — add a token endpoint on your website
Create this endpoint on your site (same-origin):
GET /.well-known/dreamcode-chat/token?client_token=YOUR_API_TOKEN
Your backend endpoint must: (1) detect current domain from Host, (2) sign a request with HMAC using your Server auth secret,
(3) call Dreamcode to issue a short-lived token, (4) return JSON to the browser.
Dreamcode endpoint to call from your backend
POST https://dreamcode.am/api/widget/issue-token/
Body JSON:
{"domain": "example.com"}
Headers:
X-Client-Token: YOUR_API_TOKEN
X-Timestamp: unix_seconds
X-Nonce: random_string
X-Signature: base64url(hmac_sha256(secret, "token\ndomain\nts\nnonce")) (no "=")
Step C — keep the same script tag
No changes are needed in your HTML script tag:
<script src="https://dreamcode.am/widget/YOUR_API_TOKEN.js" async></script>
React: load the widget script
Option 1 (recommended): put the script tag into your HTML (for example public/index.html).
<!-- public/index.html -->
<script src="https://dreamcode.am/widget/YOUR_API_TOKEN.js" async></script>
Option 2: inject the script from React (if you need it programmatically).
import { useEffect } from "react";
export function DreamcodeChatWidget() {
useEffect(() => {
const s = document.createElement("script");
s.src = "https://dreamcode.am/widget/YOUR_API_TOKEN.js";
s.async = true;
document.body.appendChild(s);
return () => {
document.body.removeChild(s);
};
}, []);
return null;
}
Django: implement the secure token endpoint
This is the endpoint your site must expose in Secure mode:
GET /.well-known/dreamcode-chat/token?client_token=YOUR_API_TOKEN
# urls.py (on your website)
from django.urls import path
from .views import dreamcode_chat_token
urlpatterns = [
path('.well-known/dreamcode-chat/token', dreamcode_chat_token),
]
# views.py (on your website)
import base64
import hashlib
import hmac
import os
import time
import requests
from django.http import JsonResponse
from django.views.decorators.http import require_GET
def _b64url_no_pad(b: bytes) -> str:
return base64.urlsafe_b64encode(b).decode('ascii').rstrip('=')
@require_GET
def dreamcode_chat_token(request):
# Validate client_token (optional but recommended)
client_token = request.GET.get('client_token', '')
if not client_token:
return JsonResponse({'error': 'client_token is required'}, status=400)
# Store these as environment variables on YOUR SERVER (never in JS)
secret = os.environ.get('DREAMCODE_SERVER_AUTH_SECRET', '')
if not secret:
return JsonResponse({'error': 'Server auth secret not configured'}, status=500)
# Use current request host as domain
domain = (request.get_host() or '').split(':')[0]
ts = str(int(time.time()))
nonce = os.urandom(16).hex()
msg = f"{client_token}\n{domain}\n{ts}\n{nonce}".encode('utf-8')
sig = _b64url_no_pad(hmac.new(secret.encode('utf-8'), msg, hashlib.sha256).digest())
r = requests.post(
'https://dreamcode.am/api/widget/issue-token/',
json={'domain': domain},
headers={
'X-Client-Token': client_token,
'X-Timestamp': ts,
'X-Nonce': nonce,
'X-Signature': sig,
},
timeout=5,
)
# Proxy Dreamcode response back to the browser
try:
data = r.json()
except Exception:
data = {'error': 'Invalid response from Dreamcode'}
return JsonResponse(data, status=r.status_code)
/.well-known/dreamcode-chat/token.