What is basepath?
The gateway.controlui.basepath setting tells the OpenClaw Control UI to serve its assets and API calls under a custom URL path prefix. By default, the Control UI is served at the root path /.
When you host multiple services behind a single domain using a reverse proxy, you need each service at a different path:
https://tools.company.com/openclaw/ β OpenClaw Control UI
https://tools.company.com/grafana/ β Grafana
https://tools.company.com/jenkins/ β JenkinsWithout basepath, the Control UI expects to be at / and all its internal links, API calls, and static assets will break when served from a subpath.
Configuration
Set via CLI
openclaw configure --set gateway.controlui.basepath=/openclaw
openclaw gateway restartSet in config file
{
"gateway": {
"controlui": {
"basepath": "/openclaw",
"allowedorigins": ["https://tools.company.com"]
}
}
}Environment variable
export OPENCLAW_GATEWAY_CONTROLUI_BASEPATH=/openclaw
openclaw gateway restartImportant rules
- Always start with a slash:
/openclawnotopenclaw - No trailing slash:
/openclawnot/openclaw/ - Update allowedorigins: The origin must match the external URL, not the internal one
- API calls shift too: The gateway API moves from
/api/...to/openclaw/api/...
Reverse proxy examples
Nginx
location /openclaw/ {
proxy_pass http://localhost:18789/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}The key detail: proxy_pass http://localhost:18789/ with a trailing slash strips the /openclaw/ prefix before forwarding to the gateway. Combined with basepath=/openclaw, the UI generates correct links.
Caddy
tools.company.com {
handle_path /openclaw/* {
reverse_proxy localhost:18789
}
}Caddyβs handle_path strips the prefix automatically.
Traefik
# docker-compose.yml labels
labels:
- "traefik.http.routers.openclaw.rule=Host(`tools.company.com`) && PathPrefix(`/openclaw`)"
- "traefik.http.routers.openclaw.middlewares=openclaw-strip"
- "traefik.http.middlewares.openclaw-strip.stripprefix.prefixes=/openclaw"
- "traefik.http.services.openclaw.loadbalancer.server.port=18789"Kubernetes Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: openclaw
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: tools.company.com
http:
paths:
- path: /openclaw(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: openclaw
port:
number: 18789Full configuration example
Putting it all together β OpenClaw behind Nginx with TLS, custom basepath, and proper origin enforcement:
{
"gateway": {
"bind": "lan",
"controlui": {
"basepath": "/openclaw",
"allowedorigins": ["https://tools.company.com"],
"allowinsecureauth": false
}
}
}openclaw gateway restartAccess at: https://tools.company.com/openclaw/
Troubleshooting
Blank page or 404
The most common issue: the reverse proxy is not stripping the path prefix correctly. Check:
- Does your proxy strip
/openclawbefore forwarding? - Does
basepathin OpenClaw config match the proxy path? - Open browser DevTools β Network tab β check if API calls go to
/openclaw/api/...or just/api/...
WebSocket connection fails
The Control UI uses WebSockets. Make sure your proxy passes Upgrade and Connection headers. For Nginx:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";Static assets return 404
If CSS/JS files load from /assets/... instead of /openclaw/assets/..., the basepath setting is not being picked up. Verify with:
openclaw statusLook for controlui.basepath in the output.