Reverse Proxy
Serve your documentation at /docs using nginx, Apache, Caddy, Traefik, or HAProxy. Includes tested configuration snippets for each reverse proxy.
If you already run nginx, Apache, Caddy, Traefik, or HAProxy, add a location/route block that forwards /docs traffic to your Jamdesk subdomain.
Prerequisites
- Access to your web server configuration
- Your Jamdesk subdomain (found in dashboard settings)
nginx
Add a location block to proxy /docs requests to Jamdesk:
server {
listen 443 ssl;
server_name yoursite.com;
# Your existing configuration...
# Proxy /docs to Jamdesk
location /docs {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# Required for domain verification
proxy_set_header X-Jamdesk-Forwarded-Host $host;
}
# Next.js static assets (JS, CSS)
location /_next/ {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
}
# Jamdesk assets (fonts, images, branding)
location /_jd/ {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
}
}
Replace YOUR_SLUG with your actual Jamdesk subdomain.
Path handling matters. The proxy_pass URL has no trailing path, so nginx preserves the original request path. A request to /docs/page proxies to jamdesk.app/docs/page. If you add a trailing slash (proxy_pass https://...jamdesk.app/), the /docs prefix gets stripped. Keep it exactly as shown above.
After updating your configuration, reload nginx:
sudo nginx -t && sudo systemctl reload nginx
Apache
Use mod_proxy to forward /docs requests to Jamdesk:
<VirtualHost *:443>
ServerName yoursite.com
# Your existing configuration...
# Enable proxy modules
ProxyRequests Off
SSLProxyEngine On
# Proxy /docs to Jamdesk
ProxyPass /docs https://YOUR_SLUG.jamdesk.app/docs
ProxyPassReverse /docs https://YOUR_SLUG.jamdesk.app/docs
# Next.js static assets (JS, CSS)
ProxyPass /_next https://YOUR_SLUG.jamdesk.app/_next
ProxyPassReverse /_next https://YOUR_SLUG.jamdesk.app/_next
# Jamdesk assets (fonts, images, branding)
ProxyPass /_jd https://YOUR_SLUG.jamdesk.app/_jd
ProxyPassReverse /_jd https://YOUR_SLUG.jamdesk.app/_jd
<Location /docs>
RequestHeader set X-Forwarded-Host "yoursite.com"
RequestHeader set X-Forwarded-Proto "https"
# Required for domain verification
RequestHeader set X-Jamdesk-Forwarded-Host "yoursite.com"
</Location>
</VirtualHost>
Ensure the required modules are enabled:
sudo a2enmod proxy proxy_http ssl headers
sudo systemctl reload apache2
Caddy
Caddy provides simple reverse proxy configuration with automatic HTTPS:
yoursite.com {
# Your existing configuration...
handle /docs* {
reverse_proxy https://YOUR_SLUG.jamdesk.app {
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
# Required for domain verification
header_up X-Jamdesk-Forwarded-Host {host}
}
}
# Next.js static assets and Jamdesk assets
handle /_next/* {
reverse_proxy https://YOUR_SLUG.jamdesk.app {
header_up Host {upstream_hostport}
}
}
handle /_jd/* {
reverse_proxy https://YOUR_SLUG.jamdesk.app {
header_up Host {upstream_hostport}
}
}
# Handle other routes
handle {
# Your main site configuration
}
}
Reload Caddy after changes:
sudo systemctl reload caddy
Traefik
For Traefik users, configure a router and service:
http:
routers:
docs-router:
rule: "Host(`yoursite.com`) && (PathPrefix(`/docs`) || PathPrefix(`/_next`) || PathPrefix(`/_jd`))"
service: jamdesk-docs
middlewares:
- jamdesk-headers
tls: {}
middlewares:
jamdesk-headers:
headers:
customRequestHeaders:
# Required for domain verification
X-Jamdesk-Forwarded-Host: "yoursite.com"
services:
jamdesk-docs:
loadBalancer:
servers:
- url: "https://YOUR_SLUG.jamdesk.app"
passHostHeader: falseHAProxy
For HAProxy, add backend and ACL rules:
frontend https
bind *:443 ssl crt /etc/ssl/certs/yoursite.pem
# Route /docs and assets to Jamdesk backend
acl is_docs path_beg /docs
acl is_next path_beg /_next
acl is_jd path_beg /_jd
use_backend jamdesk_docs if is_docs or is_next or is_jd
# Default backend for other requests
default_backend main_site
backend jamdesk_docs
server jamdesk YOUR_SLUG.jamdesk.app:443 ssl verify none
http-request set-header Host YOUR_SLUG.jamdesk.app
http-request set-header X-Forwarded-Host %[req.hdr(host)]
# Required for domain verification
http-request set-header X-Jamdesk-Forwarded-Host %[req.hdr(host)]
Forward Your Root Files Too
robots.txt, sitemap.xml, llms.txt, and llms-full.txt are served from the domain root, not from under /docs — a proxy that only forwards /docs, /_next, and /_jd leaves these served by your own site (or not served at all), which breaks AI-agent discovery and costs you SEO regardless of anything else on this page.
Add the same location/route pattern you used for /docs above, for each of these four paths. For nginx:
location = /robots.txt {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
proxy_set_header X-Jamdesk-Forwarded-Host $host;
}
location = /sitemap.xml {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
proxy_set_header X-Jamdesk-Forwarded-Host $host;
}
location = /llms.txt {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
proxy_set_header X-Jamdesk-Forwarded-Host $host;
}
location = /llms-full.txt {
proxy_pass https://YOUR_SLUG.jamdesk.app;
proxy_ssl_server_name on;
proxy_set_header Host YOUR_SLUG.jamdesk.app;
proxy_set_header X-Jamdesk-Forwarded-Host $host;
}
The same four blocks — same headers, same upstream — apply to Apache, Caddy, Traefik, and HAProxy: copy whichever /docs block you're using above and repeat it once per path.
Only forward these if Jamdesk owns your domain root. If your main site already serves its own robots.txt or sitemap.xml, merge the two instead of overwriting one with the other.
Required Headers
Regardless of which proxy you use, ensure these headers are set:
| Header | Value | Purpose |
|---|---|---|
Host | YOUR_SLUG.jamdesk.app | Identifies the request to Jamdesk |
X-Forwarded-Host | Your domain | Tells Jamdesk which domain to use in URLs |
X-Forwarded-Proto | https | Ensures secure URL generation |
X-Jamdesk-Forwarded-Host | Your domain | Required for domain verification |
?jd_proxy=1 query marker | Appended to the upstream URL | Alternative to the header, for tools that can only rewrite a URL and can't set request headers — see Custom domain only |
The X-Jamdesk-Forwarded-Host header (or the ?jd_proxy=1 marker) is required, and going without either fails quietly.
Requests still succeed — nothing errors, which is exactly what makes it easy to miss. What breaks is subtler:
- If you haven't registered a custom domain in the dashboard, your documentation pages are served with
<meta name="robots" content="noindex">, and canonical, Open Graph, and sitemap URLs all point atYOUR_SLUG.jamdesk.appinstead of your domain. Search engines will never index your documentation. - If you have registered a custom domain, Jamdesk falls back to the domain on file, so your URLs stay correct — but it still can't tell proxy traffic apart from direct traffic to your
*.jamdesk.appsubdomain, and the Custom domain only preflight check will fail.
A 403 is the opposite problem: the header is present, but names a domain that isn't registered and active for this project.
The proxy configuration is a one-time setup. If you later change your custom domain or configuration in the Jamdesk dashboard, the proxy doesn't need to be updated - all routing decisions are made server-side based on your dashboard settings.
Troubleshooting
Verify the proxy can reach YOUR_SLUG.jamdesk.app over HTTPS. Check firewall rules and DNS resolution.
Enable SSL/TLS for the upstream connection. For nginx, add proxy_ssl_server_name on;. For Apache, enable SSLProxyEngine On.
Ensure the X-Forwarded-Host header is set correctly. This tells Jamdesk which domain to use for asset URLs and internal links.
Check that your proxy isn't following redirects. The proxy should forward the response as-is without additional redirect handling.
If you see "Domain is not authorized to serve this content":
- Verify your domain is registered in the Jamdesk dashboard
- Complete DNS verification (TXT record) for your domain
- Ensure the
X-Jamdesk-Forwarded-Hostheader is set in your proxy configuration - Check that your domain maps to the correct project
The domain must be verified before the proxy can serve documentation.
Preflight fetches /_jd/preflight on your live domain and checks what actually reached Jamdesk. If it reports your proxy "doesn't identify itself," a request reached Jamdesk but without the header or the marker — recheck the X-Jamdesk-Forwarded-Host line in every location/route block above. See Custom domain only for what each preflight message means.
