mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-08 13:46:08 +00:00
9b91f0f42e
Fold the standalone 3x-ui-docs project (Next.js 16 + Fumadocs, deployed to docs.sanaei.dev) into docs/ so the panel and its documentation share a single source of truth, the way sing-box keeps its docs in-tree. The old repo becomes redundant and can be retired. - Import the full site under docs/ (app, components, content, lib, public, scripts, config). The self-contained pnpm project sits alongside the existing engineering notes with no filename collisions. - Re-point "Edit on GitHub" links from MHSanaei/3x-ui-docs to this repo's docs/content/docs path (docs/lib/shared.ts, docs/app/.../page.tsx). - Add docs-ci.yml and docs-deploy.yml under .github/workflows/, scoped to docs/** and run with working-directory: docs, since GitHub only runs workflows from the repo-root .github/. deploy-static.yml's GitHub Pages publish (CNAME docs.sanaei.dev) carries over unchanged. Follow-up (outside this commit): attach the docs.sanaei.dev custom domain to this repository's Pages (or set the Vercel project's root directory to docs), confirm the site is live from the monorepo, then delete MHSanaei/3x-ui-docs.
87 lines
4.1 KiB
Plaintext
87 lines
4.1 KiB
Plaintext
---
|
|
title: Subscription
|
|
description: Run the 3x-ui subscription server — base64/JSON/Clash formats, ports and paths, TLS, response headers, and custom templates.
|
|
icon: Rss
|
|
---
|
|
|
|
A **subscription** is a single URL that returns all of a client's
|
|
configurations. Client apps refresh it periodically, so when you change an
|
|
inbound, clients pick up the change automatically. The subscription server runs
|
|
as a **separate** server from the panel.
|
|
|
|
## Enable and configure
|
|
|
|
The subscription server is **on by default** (`subEnable`). Configure it in the
|
|
panel's subscription settings:
|
|
|
|
| Setting | Default | Meaning |
|
|
| ------------- | ------- | --------------------------------------------------------------- |
|
|
| `subPort` | `2096` | Listen port (separate from the panel). |
|
|
| `subListen` | _(all)_ | Bind address. |
|
|
| `subPath` | `/sub/` | Base path for raw subscription URLs. |
|
|
| `subDomain` | _(none)_| Public host; if set, the server only answers for that Host. |
|
|
| `subCertFile` / `subKeyFile` | _(none)_ | TLS cert + key — when set, the server serves **HTTPS**. |
|
|
| `subEncrypt` | `true` | Base64-encode the raw subscription body. |
|
|
| `subUpdates` | `12` | Suggested refresh interval (hours) sent to clients. |
|
|
|
|
A subscription URL looks like:
|
|
|
|
```text
|
|
https://<sub-host>:<sub-port>/sub/<sub-id>
|
|
```
|
|
|
|
where `<sub-id>` is the client's **Sub ID**.
|
|
|
|
The same Sub ID is served in several formats on different paths — the **Base64**
|
|
list at `subPath` and the **JSON** (Xray-json) config at the JSON path. Build the
|
|
URLs and preview both bodies here:
|
|
|
|
<SubscriptionBuilder />
|
|
|
|
## Output formats
|
|
|
|
The **format is chosen by path**, each with its own enable toggle:
|
|
|
|
| Format | Path | Enabled by | Output |
|
|
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
|
|
| **Raw links** | `/sub/` | always (if on) | A list of `vless://`, `vmess://`, … links (base64-encoded when `subEncrypt` is on). |
|
|
| **JSON** | `/json/` | `subJsonEnable` | Full Xray client config(s). |
|
|
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | YAML profile. |
|
|
|
|
Only enabled inbounds using **VLESS, VMess, Trojan, Shadowsocks, or Hysteria2**
|
|
appear in a subscription, ordered by their sub-sort index. Requesting `/sub/`
|
|
with an `Accept: text/html` header (or `?html=1`) returns a human-readable info
|
|
page instead of the raw body.
|
|
|
|
### Base64 vs JSON
|
|
|
|
The **Base64** body is just the newline-joined share links, standard-base64
|
|
encoded (toggle with `subEncrypt`). The **JSON** body wraps each client in a
|
|
complete Xray client config — a fixed skeleton (local mixed/HTTP inbounds, DNS,
|
|
routing, policy) plus a `proxy` outbound pointing at the inbound. 3x-ui emits a
|
|
**single config object for one client and an array for several**, uses the flat
|
|
outbound `settings` form (`address`/`port`/`id`, `level: 8`), and strips
|
|
`sockopt` from `streamSettings`.
|
|
|
|
## Response headers
|
|
|
|
Subscriptions return standard headers that compatible apps read:
|
|
|
|
- **`Subscription-Userinfo`** — `upload`, `download`, `total` (bytes; `total=0`
|
|
means unlimited) and `expire` (Unix seconds).
|
|
- **`Profile-Update-Interval`** — refresh interval in hours (`subUpdates`).
|
|
- **`Profile-Title`**, **`Support-Url`**, **`Profile-Web-Page-Url`**,
|
|
**`Announce`** — optional branding shown by some clients.
|
|
|
|
## Custom page templates
|
|
|
|
Point `subThemeDir` at a folder containing a custom info-page template to brand
|
|
the HTML subscription page. The per-client remark on each link is fully
|
|
templated — see [Share links → remark variables](/docs/config/share-links#remark-template-variables).
|
|
|
|
<Callout type="info">
|
|
Put the subscription server behind TLS (set `subCertFile`/`subKeyFile`, or a
|
|
[reverse proxy](/docs/operations/reverse-proxy)) so subscription contents
|
|
aren't exposed in transit.
|
|
</Callout>
|