Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
60417ed
ci(release): removed buggy base url default replacement
ravindra-cloudflare May 28, 2026
81c5a4d
fix(react-build): fixed typescript issue with react-draggable, hardco…
ravindra-cloudflare Jun 3, 2026
de7252e
fix(active-speaker-ui): removed default plugin support
ravindra-cloudflare Jun 3, 2026
4749660
fix: remove supportsConnectedMeetings references from react-examples
mayankofficial999 Jun 5, 2026
1798d18
Merge pull request #77 from cloudflare/fix/remove-br-support-check
ravindra-cloudflare Jun 5, 2026
6aa3a3e
feat: add a sample with a whiteboard custom plugin
ishita1805 Jun 8, 2026
6d424f5
Update react-examples/examples/plugins/src/App.tsx
ishita1805 Jun 8, 2026
f8ac1e1
Update demo-app/worker-configuration.d.ts
ishita1805 Jun 8, 2026
9fe8a17
fix: remove hardcoding
ishita1805 Jun 8, 2026
91bad05
Merge branch 'feat/custom-plugins-sample' of github.com:cloudflare/re…
ishita1805 Jun 8, 2026
d50fffa
Update react-examples/examples/plugins/src/App.tsx
ishita1805 Jun 8, 2026
b55e3ef
Update react-examples/examples/plugins/src/App.tsx
ishita1805 Jun 8, 2026
c73f9ec
Merge pull request #78 from cloudflare/feat/custom-plugins-sample
ishita1805 Jun 9, 2026
79f115e
fix: update pnpm lockfile
ishita1805 Jun 9, 2026
889f17f
Merge branch 'staging' into feat/custom-plugins-sample
ishita1805 Jun 9, 2026
baeea83
Merge pull request #79 from cloudflare/feat/custom-plugins-sample
ishita1805 Jun 9, 2026
387a55d
fix: force react build for samples
ishita1805 Jun 9, 2026
3a2b9b9
Merge branch 'feat/custom-plugins-sample' of github.com:cloudflare/re…
ishita1805 Jun 9, 2026
bb59ed6
Merge branch 'staging' into feat/custom-plugins-sample
ishita1805 Jun 9, 2026
62ac56a
Merge pull request #80 from cloudflare/feat/custom-plugins-sample
ishita1805 Jun 9, 2026
b6ebb13
feat(examples): added dynamic base uri and log in console support for…
ravindra-cloudflare Jun 15, 2026
dee0300
fix(sdk-versions): reverted incorrect replacement of sdk versions
ravindra-cloudflare Jun 15, 2026
72812d3
Merge pull request #82 from cloudflare/feat/dynamic-base-uri-log-in-c…
ravindra-cloudflare Jun 15, 2026
c943d45
fix: move rtk credentials server side
ishita1805 Jun 15, 2026
a5232c5
fix: replace all usage of vite prefix with realtimekit
ishita1805 Jun 15, 2026
76f4f03
fix: update example env
ishita1805 Jun 15, 2026
d74c1c6
fix: resolve merge conflicts
ishita1805 Jun 15, 2026
c2a2950
fix: Secure RealtimeKit credential handling
ishita1805 Jun 15, 2026
e0d437e
fix: pass generic error message to client
ishita1805 Jun 15, 2026
5e4f629
Merge pull request #83 from cloudflare/fix/creds
ravindra-cloudflare Jun 15, 2026
dbc3728
fix: update deploy action
ishita1805 Jun 15, 2026
298dd96
Merge branch 'staging' into fix/creds
ishita1805 Jun 15, 2026
ac46c93
Merge pull request #84 from cloudflare/fix/creds
ravindra-cloudflare Jun 16, 2026
1cf1e2c
Merge branch 'main' into staging
ravindra-cloudflare Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,22 @@ jobs:
env:
CLOUDFLARE_ENV: staging # for vite.config.ts to figure out which environment to build for
VITE_ENV: staging
VITE_ORG_ID: ${{ secrets.VITE_ORG_ID_STAGING }}
VITE_API_KEY: ${{ secrets.VITE_API_KEY_STAGING }}
VITE_BASE_URL: staging.realtime.cloudflare.com

- name: Configure RealtimeKit API key
run: pnpm wrangler secret put REALTIMEKIT_API_KEY --env staging <<< "$REALTIMEKIT_API_KEY"
working-directory: ./demo-app
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
REALTIMEKIT_API_KEY: ${{ secrets.REALTIMEKIT_API_KEY_STAGING }}

- name: Configure RealtimeKit org ID
run: pnpm wrangler secret put REALTIMEKIT_ORG_ID --env staging <<< "$REALTIMEKIT_ORG_ID"
working-directory: ./demo-app
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
REALTIMEKIT_ORG_ID: ${{ secrets.REALTIMEKIT_ORG_ID_STAGING }}

- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v4
Expand All @@ -52,6 +65,3 @@ jobs:
env:
VITE_ENV: staging
CLOUDFLARE_ENV: staging # for vite.config.ts to figure out which environment to deploy to
VITE_API_KEY: ${{ secrets.VITE_API_KEY_STAGING }}
VITE_ORG_ID: ${{ secrets.VITE_ORG_ID_STAGING }}
VITE_BASE_URL: staging.realtime.cloudflare.com
33 changes: 16 additions & 17 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,28 @@ jobs:
run: pnpm install --frozen-lockfile
working-directory: ./

- name: Debug env vars
run: |
echo "VITE_BASE_URL is set: ${{ secrets.VITE_BASE_URL != '' }}"
echo "VITE_API_KEY is set: ${{ secrets.VITE_API_KEY != '' }}"
echo "VITE_ORG_ID is set: ${{ secrets.VITE_ORG_ID != '' }}"
echo "VITE_BASE_URL length: ${#VITE_BASE_URL}"
env:
VITE_BASE_URL: realtime.cloudflare.com
VITE_API_KEY: ${{ secrets.VITE_API_KEY }}
VITE_ORG_ID: ${{ secrets.VITE_ORG_ID }}

- name: Build
run: pnpm run build
working-directory: ./demo-app
env:
CLOUDFLARE_ENV: production # for vite.config.ts to figure out which environment to build for
VITE_ENV: production
VITE_ORG_ID: ${{ secrets.VITE_ORG_ID }}
VITE_API_KEY: ${{ secrets.VITE_API_KEY }}
VITE_BASE_URL: realtime.cloudflare.com

- name: Configure RealtimeKit API key
run: pnpm wrangler secret put REALTIMEKIT_API_KEY --env production <<< "$REALTIMEKIT_API_KEY"
working-directory: ./demo-app
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
REALTIMEKIT_API_KEY: ${{ secrets.REALTIMEKIT_API_KEY }}

- name: Configure RealtimeKit org ID
run: pnpm wrangler secret put REALTIMEKIT_ORG_ID --env production <<< "$REALTIMEKIT_ORG_ID"
working-directory: ./demo-app
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
REALTIMEKIT_ORG_ID: ${{ secrets.REALTIMEKIT_ORG_ID }}

- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v4
Expand All @@ -63,6 +65,3 @@ jobs:
env:
VITE_ENV: production
CLOUDFLARE_ENV: production # for vite.config.ts to figure out which environment to deploy to
VITE_API_KEY: ${{ secrets.VITE_API_KEY }}
VITE_ORG_ID: ${{ secrets.VITE_ORG_ID }}
VITE_BASE_URL: realtime.cloudflare.com
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ realtimekit-web-examples/
| Update SDK versions | `<workspace>/update-cloudflare-realtime-deps.sh` | Fetches from npm; pass `--env staging\|prod` |
| Gallery example catalog | `demo-app/app/utils/react.ts`, `angular.ts`, `vanilla.ts` | Hardcoded; new examples won't appear without editing |
| CI / deploy config | `.github/workflows/` | Per-framework staging + prod deploy workflows |
| API credentials | `demo-app/.env.example` | `VITE_ORG_ID`, `VITE_API_KEY`, `VITE_BASE_URL`, `VITE_ENV` |
| API credentials | `demo-app/.dev.vars.example` | `REALTIMEKIT_ORG_ID`, `REALTIMEKIT_API_KEY`, `REALTIMEKIT_BASE_URL` |

## COMMANDS

Expand Down Expand Up @@ -71,6 +71,6 @@ cd demo-app && pnpm dev

- `pnpm-workspace.yaml` has a stale path: `recording-sdk-app-examples/react-examples/*` (actual dir: `recording-sdk-app-samples`) — this workspace glob is broken
- `demo-app/README.md` contains only "TODO" — consult root `README.md`
- `VITE_BASE_URL=realtime.cloudflare.com` in `.env.example` is a legacy URL (pre-Cloudflare branding) — verify the actual endpoint in CI secrets
- `REALTIMEKIT_BASE_URL=realtime.cloudflare.com` is the server-side API base hostname for production; public SDK example builds use `VITE_BASE_URL` with staging using `staging.realtime.cloudflare.com`
- Node version unspecified in the repo; CI uses Node 20 — match locally
- `@dyteinternals/utils` in `recording-sdk-app-samples/react-examples/recording-with-watermark/package.json` is a vestigial upstream dependency
7 changes: 1 addition & 6 deletions angular-examples/.env.examples
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# API Credentials
VITE_ORG_ID=
VITE_API_KEY=

# API Base URL
VITE_BASE_URL=realtime.cloudflare.com


VITE_ENV=production
# VITE_ENV=production
# VITE_ENV=production
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ export class AppComponent implements OnInit {
if (!this.meeting) {
try {
// Initialize RealtimeKit client
const baseURI = searchParams.get('baseURI') || environment.baseUrl;
const logInConsole = searchParams.get('logInConsole') === 'true';

const meeting = await RealtimeKitClient.init({
authToken,
baseURI: environment.baseUrl,
baseURI,
modules: { devTools: { logs: logInConsole } },
});

this.meeting = meeting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ export class AppComponent {
return;
}

const baseURI = searchParams.get('baseURI') || environment.baseUrl;
const logInConsole = searchParams.get('logInConsole') === 'true';

const meeting = await RealtimeKitClient.init({
authToken,
baseURI: environment.baseUrl,
baseURI,
modules: { devTools: { logs: logInConsole } },
});

this.$meetingEl.meeting = meeting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ export class AppComponent {
return;
}

const baseURI = searchParams.get('baseURI') || environment.baseUrl;
const logInConsole = searchParams.get('logInConsole') === 'true';

const meeting = await RealtimeKitClient.init({
authToken,
baseURI: environment.baseUrl,
baseURI,
modules: { devTools: { logs: logInConsole } },
});

this.$meetingEl.meeting = meeting;
Expand Down
3 changes: 3 additions & 0 deletions demo-app/.dev.vars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
REALTIMEKIT_ORG_ID=your-org-id-here
REALTIMEKIT_API_KEY=your-api-key-here
REALTIMEKIT_BASE_URL=realtime.cloudflare.com
9 changes: 1 addition & 8 deletions demo-app/.env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
# Dyte API Credentials
# Please use this ORG ID in order for presets to work
VITE_ORG_ID=05dc4990-76b0-44f8-adc9-42d27cd9f68f
VITE_API_KEY=your-api-key-here

# Dyte API Base URL
VITE_BASE_URL=realtime.cloudflare.com

# Browser-exposed environment only. Do not put API credentials in VITE_* vars.
VITE_ENV=production
3 changes: 2 additions & 1 deletion demo-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ html-examples
*.tsbuildinfo

.env.production
.env.staging
.env.staging
.dev.vars
9 changes: 5 additions & 4 deletions demo-app/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ demo-app/
│ └── app.ts # Cloudflare Worker entry point (SSR)
├── worker-configuration.d.ts # Auto-generated Wrangler env bindings — do not edit manually
├── .env.example
├── .dev.vars.example
├── vite.config.ts
└── tsconfig.cloudflare.json # Primary TS config; includes .react-router/types/**/*
```
Expand Down Expand Up @@ -52,7 +53,7 @@ demo-app/
## COMMANDS

```bash
pnpm dev # Local dev (requires .env with valid VITE_ORG_ID + VITE_API_KEY)
pnpm dev # Local dev (requires .dev.vars with valid REALTIMEKIT_ORG_ID + REALTIMEKIT_API_KEY)
pnpm build # Production build
pnpm deploy # Build + wrangler deploy
pnpm typecheck # wrangler types + react-router typegen + tsc
Expand All @@ -61,7 +62,7 @@ pnpm cf-typegen # Regenerate worker-configuration.d.ts

## NOTES

- `.env.example` includes a real shared demo `VITE_ORG_ID` — intentional for preset compatibility
- `VITE_BASE_URL=dyte.io` in `.env.example` is a legacy URL — verify actual endpoint in CI secrets
- `.env.example` is browser-exposed and must not include API credentials
- `.dev.vars.example` documents local Worker runtime credentials for meeting creation
- `demo-app/README.md` is blank ("TODO") — this file is the authoritative reference
- Stack: React 18 + React Router 7 + Tailwind CSS v4 + `@cloudflare/vite-plugin` + Wrangler
- Stack: React 18 + React Router 7 + Tailwind CSS v4 + `@cloudflare/vite-plugin` + Wrangler
16 changes: 9 additions & 7 deletions demo-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,29 @@ This application lists, filters, and launches all SDK examples. It creates meeti

### Environment Setup

Copy `.env.example` to `.env` and fill in your credentials:
Copy `.env.example` to `.env` for browser-safe Vite values, and copy `.dev.vars.example` to `.dev.vars` for Worker runtime credentials:

```bash
cp .env.example .env
cp .dev.vars.example .dev.vars
```

Required environment variables:

| Variable | Description |
|----------|-------------|
| `VITE_ORG_ID` | Your RealtimeKit organization ID |
| `VITE_API_KEY` | Your RealtimeKit API key |
| `VITE_BASE_URL` | RealtimeKit API base URL (e.g., `https://api.cloudflare.com/client/v2` or legacy `https://api.dyte.io/v2`) |
| `VITE_ENV` | Environment identifier (e.g., `staging`, `production`) |
| `REALTIMEKIT_ORG_ID` | Your RealtimeKit organization ID, stored in `.dev.vars` locally or Worker secrets in deploys |
| `REALTIMEKIT_API_KEY` | Your RealtimeKit API key, stored in `.dev.vars` locally or Worker secrets in deploys |
| `REALTIMEKIT_BASE_URL` | RealtimeKit API base hostname (e.g., `realtime.cloudflare.com`) |

### Development

```bash
# Install dependencies
pnpm install

# Start dev server (requires .env with valid credentials)
# Start dev server (requires .dev.vars with valid credentials)
pnpm dev
```

Expand Down Expand Up @@ -79,7 +80,8 @@ demo-app/
├── worker-configuration.d.ts # Auto-generated Wrangler env bindings
├── vite.config.ts
├── wrangler.jsonc
└── .env.example
├── .env.example
└── .dev.vars.example
```

## Adding Examples to the Gallery
Expand Down Expand Up @@ -129,7 +131,7 @@ The gallery catalog is **hardcoded** (not auto-discovered). To add a new example

- **Type errors after route changes**: Run `pnpm typecheck` to regenerate `.react-router/types/`
- **Wrangler env binding errors**: Run `pnpm cf-typegen` to update `worker-configuration.d.ts`
- **Meeting creation fails**: Verify your `.env` contains valid `VITE_ORG_ID` and `VITE_API_KEY`
- **Meeting creation fails**: Verify your `.dev.vars` contains valid `REALTIMEKIT_ORG_ID` and `REALTIMEKIT_API_KEY`

## Related

Expand Down
7 changes: 0 additions & 7 deletions demo-app/app/api/index.ts

This file was deleted.

61 changes: 27 additions & 34 deletions demo-app/app/api/meeting.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
export const createMeeting = async ({
meetingName,
recordOnStart,
aiSummary
}: {
meetingName: string;
recordOnStart: boolean;
aiSummary: boolean;
}) => {
const apiKey = import.meta.env.VITE_API_KEY;
const orgId = import.meta.env.VITE_ORG_ID;
const baseUrl = `https://api.${import.meta.env.VITE_BASE_URL}/v2`;
const authHeader = btoa(`${orgId}:${apiKey}`);
const response = await fetch(`${baseUrl}/meetings`, {
method: "POST",
headers: {
"Authorization": `Basic ${authHeader}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
title: meetingName ?? "RealtimeKit Meeting",
record_on_start: recordOnStart,
summarize_on_end: aiSummary
})
})

const data = await response.json() as { message: string, data: { id: string } };

if (!response.ok) {
throw new Error(data.message || `API request failed with status ${response.status}`);
}

return data;
}
import type { ActionFunctionArgs } from "react-router";
import { apiError, getAuthHeaders, getRealtimeKitConfig } from "./realtimekit.server";

export const action = async ({ context, request }: ActionFunctionArgs) => {
try {
const { meetingName, recordOnStart, aiSummary } = await request.json() as {
meetingName: string;
recordOnStart: boolean;
aiSummary: boolean;
};
const config = getRealtimeKitConfig(context);
const response = await fetch(`${config.baseUrl}/meetings`, {
method: "POST",
headers: getAuthHeaders(config),
body: JSON.stringify({
title: meetingName ?? "RealtimeKit Meeting",
record_on_start: recordOnStart,
summarize_on_end: aiSummary,
}),
});
const data = await response.json();

return Response.json(data, { status: response.status });
} catch (error) {
return apiError(error);
}
};
Loading
Loading