> ## Documentation Index
> Fetch the complete documentation index at: https://nexohub.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Proxy config

> plugins/nexohub/config.yml, on your Velocity or BungeeCord proxy.

Everything is here. Backends only need the address and the secret.

```yaml theme={null}
http:
  bind: 0.0.0.0
  port: 8085
  public_address: ""
  secret: ""

packs:
  host: hermes
  mixed_content: false

groups: {}
servers: {}

notify:
  webhook_url: ""
```

On a new install the secret is generated for you on first start. Copy it into each
backend and you are done.

## Where the pack comes from

```yaml theme={null}
packs:
  host: hermes
```

| | |
| - | - |
| `hermes` | Nexo's own host. No account, no keys, nothing of yours exposed. The default |
| `polymath` | Nexo's older free host |
| `s3` | any S3 bucket: AWS, Cloudflare R2, Backblaze, Hetzner |
| `lobfile` | lobfile.com, needs an API key |
| `proxy` | your proxy serves it |

Anything but `proxy` is a Nexo pack server type, so configure the host itself the normal
Nexo way under `Pack.server`. Pick `proxy` and you also need `http.port` open to players
and `http.public_address` set to an address that works from outside your network. See
[hosting](/guides/hosting).

<Note>
  Multipack needs a host whose URL contains the pack hash: `hermes`, `s3` or `proxy`.
  NexoHub warns on startup if you pick one of the other two with multipack on.
</Note>

## Do your backends run different HUDs or models?

```yaml theme={null}
packs:
  mixed_content: false
```

`false` if they all run the same ones. Every backend builds the same thing, so they share
one pack and one download with nothing to merge.

`true` if they differ. The hub gives every backend the union of what they all generated,
merged into one pack, so a HUD defined only on pvp still shows up for a player on lobby.
This is the only way BetterHUD's and ModelEngine's assets reach the other backends, since
their files stay on the server you installed them on.

<Warning>
  Do not set `true` alongside a generator you turned `off` under [generators](#settings).
  That one numbers on its own, and merging it in gives one backend another's models.
</Warning>

## Groups and per-server settings

Most networks need none of this. It is here for when four servers want the same thing and
you would rather say it once.

Files go in `nexo-data/`, and settings go in `config.yml`, in the same three layers:

| Layer | Files | Settings |
| - | - | - |
| everyone | `_shared/` | `defaults:` |
| some backends | `groups/<name>/` | `groups.<name>:` |
| one backend | `servers/<name>/` | `servers.<name>:` |

Each wins over the one above it.

```yaml theme={null}
groups:
  minigames:
    servers: [bedwars, skywars]
    poll_seconds: 30

servers:
  pvp:
    prune: false
```

A group with just a list of backends still works and layers files only.

## MultiPack per server

NexoHub distributes Nexo's `multipack.yml` and every template pack, but Nexo normally
keeps a player's selection on one backend. Make the selection a property of the backend
instead when a template belongs to one gamemode:

```yaml theme={null}
multipack:
  servers:
    lobby: [earth]
    earth: [earth]
    practice: []
```

On every server switch the proxy sends that backend's complete selection to Nexo. In the
example a player starts the Earth download immediately after joining lobby, still has it
enabled on Earth, and loses it again when entering practice. An empty list is meaningful:
it disables every optional template. Leave a backend out to retain Nexo's ordinary,
per-player MultiPack choice there.

The template folders and Nexo config themselves belong in the shared layer:

```text theme={null}
nexo-data/_shared/multipack.yml
nexo-data/_shared/pack/template_packs/earth/
```

Nexo's base pack can arrive first during the pre-join phase; the configured template is
offered immediately after the backend connection completes. That makes `lobby: [earth]`
the preloading option, rather than making Earth download for players who join practice
directly.

### Settings

Anything in the table goes in any of the three layers.

| Setting | Default | What it does |
| - | - | - |
| `reload_after_sync` | `true` | reload Nexo when new files arrive |
| `reload_timeout_seconds` | `60` | how long Nexo gets to build a pack before it counts as failed |
| `poll_seconds` | `60` | how often a backend re-asks the hub. `0` never asks |
| `prune` | `true` | delete files the hub owns and no longer has, so a backend cannot drift |
| `exclude` | `[]` | paths under `plugins/` a backend never receives |
| `contribute` | `true` | publish what BetterHUD and friends build there |
| `contribute_exclude` | `[]` | `external_packs/` entries a backend keeps to itself |
| `generated_prefixes` | `[generated-]` | `external_packs/` folders whose name starts with one of these are a plugin's output. See [any other plugin](/guides/plugin-packs#any-other-plugin) |
| `preserve` | `Pack.server` | settings a push must never overwrite |
| `mirror_obfuscation_cache` | `true` | reuse obfuscation another backend already did |
| `obfuscation_wait_seconds` | `180` | how long to wait for it |
| `generators` | | see below |

`generators` decides what NexoHub does for one asset-building plugin:

```yaml theme={null}
generators:
  betterhud: share-files
```

`managed` is the default and holds that plugin's numbering on the hub, so backends agree
without holding each other's files. `share-files` sends its files across the network
instead. `off` leaves it alone. Keys are `betterhud`, `bettermodel`, `modelengine`,
`mythichud`, `animotions`, `overdrive` and `tooltips`.

`share-files` works per backend. Only the backends set to it send their files and receive
each other's, so a server left on `managed` keeps its own models even when others share
theirs. Set it for a [group](#groups-and-per-server-settings) to share between some servers
only.

You only need `share-files` if a backend says at startup that it runs a version NexoHub
cannot follow. It names the key to set.

<Note>
  A backend that sets one of these in its own `config.yml` keeps its own value and says so
  at startup. Delete the line there to hand it back. See
  [bridge config](/reference/bridge-config#overriding-the-hub-on-one-backend).
</Note>

## Notifications

```yaml theme={null}
notify:
  webhook_url: ""
  events: [push, validation_failed, reload_failed, collision, version_drift, rollback, stage]
```

Anything that accepts `{"content": "..."}`, so a Discord webhook works. Blank sends
nothing. Drop `push` from `events` to hear only about things that need you.

## Everything else

You are unlikely to touch any of these.

| Setting | Default | What it does |
| - | - | - |
| `http.bind` | `0.0.0.0` | interface the hub listens on |
| `http.api_address` | `""` | put the backend-only routes on their own port: `8086`, or `"10.0.0.1:8086"`. Blank shares the public one. See [exposure](/guides/exposure) |
| `sync.watch` | `true` | push automatically when `nexo-data/` changes |
| `sync.debounce_seconds` | `3` | how long to wait for edits to settle first |
| `sync.validate` | `true` | parse every file before pushing, and push nothing if one fails |
| `sync.snapshots` | `20` | how many versions of `nexo-data/` to keep for `/nexohub rollback` |
| `sync.push_on_server_populate` | `true` | catch a backend up when its first player joins |
| `packs.collect_generated` | `true` | off refuses generated output network-wide |
| `packs.share_sources` | `true` | off refuses generator source files network-wide |
| `packs.keep` | `5` | pack zips kept on disk. One in use is never deleted |
| `packs.verify_hash` | `true` | reject an upload whose bytes do not match its hash |
| `packs.claim_timeout_seconds` | `120` | before another backend may retry a stalled upload |

Most of these ship commented out. They still work if you write them.

<Note>
  `packs.hosting` and `packs.delegate` were replaced by `packs.host`, and
  `packs.contributions` by `packs.mixed_content`, and `http.api_port`/`http.api_bind` by
  `http.api_address`. Every old spelling still works, so there is nothing you have to
  change.
</Note>

## Files the hub writes

| Path | Contents |
| - | - |
| `config.yml` | this file |
| `.hubstate.json` | what each backend last reported |
| `packurls.json` | published external links, only when delegating |
| `packchoices.json` | which pack the network serves |
| `nexo-data/` | your files |
| `packs/`, `contributions/`, `sources/`, `snapshots/` | what the hub is holding |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.