---
sidebar_position: 10
sidebar_label: Deploying
---

# Deploying a Next.js app

On Vercel, or any host that runs Next.js: nothing realtime is kept on your servers, so serverless functions, edge functions and several instances all work as they are.

## Its settings

| | |
|---|---|
| `WORDPLUS_SITE`, `WORDPLUS_SECRET` | from your app in WordPlus Cloud |
| `WORDPLUS_LOCAL_KEY` | yours: kept as long as the app |

On Vercel, set them in the project Environment Variables, the same for Production and Preview. Never as `NEXT_PUBLIC_`: the key reaches pages through `config()`, which is what it is for.

## Its addresses

Add every address your pages are served from to the app in WordPlus Cloud: scheme, host and port exactly (`https://shop.example.com`, `https://www.shop.example.com`). A page anywhere else is refused with `wrong_origin`. Up to 20 addresses an app. If your server hears [webhooks](sending.md#webhooks), set their address there too.

Each preview deployment has its own address. Add the ones you test from, such as the stable address of a branch (`https://shop-git-staging-you.vercel.app`), or keep a second app in WordPlus Cloud for previews, with its own key and secret in the Preview environment.

## Its files

`realtime-worker.js`, `realtime-rooms.min.js`, `realtime-rooms-e2ee.worker.js` and `realtime-ui.min.js` are in `public/`, copied by `postinstall` on every build, so each deployment serves the ones its package came with. A browser runs a worker only from the origin of the page itself, which `public/` is.

## Rendering

- **`config()` is per user:** render it in a dynamic layout or page (one that reads cookies is), never in a statically generated one, which would hand the keys of one user to everyone.
- **Pages without a user** may connect with `config( null )`: the rooms declared `public: true` are theirs, with grants that may be cached with the page.

## Content Security Policy

If your app sends one (in `middleware.ts` or `next.config` headers), let pages reach the WordPlus Cloud servers (the realtime servers, which may move a connection to another of them, and the media servers for group calls) and run the workers from your own address:

```text
connect-src 'self' https://*.wordplus.cloud wss://*.wordplus.cloud;
worker-src 'self';
```

## Clocks

Your server signs what it sends with the time. Hosts keep theirs synced. A clock more than 5 minutes off has its emits refused with `stale_signature`.
