> ## Documentation Index
> Fetch the complete documentation index at: https://docs.magic-resume.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud Mode

> How cloud mode wires Clerk, the Core API, and the agent backend into Magic Resume.

Cloud mode turns on three things that are off in self-hosted:

1. **Clerk authentication** — login required, JWTs attached to every API request.
2. **Cloud sync** — resumes round-trip through a NestJS **Core API**, with version history and resume sharing.
3. **agent-service** (TypeScript, backend-side) — chat, interview, translation, JD-optimize, PDF parse.

## How mode detection works

`apps/web/src/lib/config/app.ts` resolves the mode:

```ts theme={null}
// pseudo-code
const explicit = process.env.NEXT_PUBLIC_APP_MODE
const hasClerk = !!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY

export const APP_MODE =
  explicit ?? (hasClerk ? 'cloud' : 'self-hosted')
```

`src/middleware.ts` switches at module load between Clerk's `clerkMiddleware` and a no-op handler based on this. There is no runtime toggle — the mode is baked at build time.

<Warning>
  If you set `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` but forget `NEXT_PUBLIC_API_URL`, the app will still boot in cloud mode and every authenticated request will 404. Set both, or neither.
</Warning>

## Environment variables

| Variable                            | Required (cloud) | Purpose                                                                                                                                                           |
| ----------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_APP_MODE`              | optional         | `cloud`. Defaults to `cloud` if a Clerk key is present.                                                                                                           |
| `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | yes              | Public Clerk key. Also triggers cloud-mode auto-detection.                                                                                                        |
| `CLERK_SECRET_KEY`                  | yes              | Server-side Clerk key.                                                                                                                                            |
| `NEXT_PUBLIC_API_URL`               | yes              | The **gateway** origin — one URL for the whole backend (dev default `http://localhost:3110`). The gateway routes `/api/*` to the Core API / agent by path prefix. |

## Backend services

The backend (Core API + agent) is deployed **separately** from this monorepo, fronted by a single **gateway**. For local cloud-mode development, run the backend and point `NEXT_PUBLIC_API_URL` at its gateway (dev default `http://localhost:3110`) — the frontend only ever needs that one URL. If you only want to develop the frontend, self-hosted mode is faster.

## Auth flow

* Clerk issues a JWT on sign-in.
* `apps/web/src/lib/api/httpClient.ts` attaches that JWT as a `Bearer` token via an Axios request interceptor (`configureHttpClient`).
* Both `httpClient.api` and `httpClient.agent` point at the same gateway origin and share the same interceptor — you should not pass tokens manually.

See [Architecture → HTTP clients](/en/architecture/http-clients) for the full request path.
