To serve your documentation through a custom reverse proxy, you must configure routing rules, caching policies, and header forwarding.
When you implement a reverse proxy, monitor for potential issues with domain verification, SSL certificate provisioning, authentication flows, performance, and analytics tracking.
Choose your deployment approach
Mintlify supports two reverse proxy configurations depending on your subpath requirements.
- Host at
/docs: Use mintlify.dev as the proxy target. Enable the Host at /docs toggle on the Custom domain setup page in your dashboard. This is a simpler configuration with fewer routes.
- Custom subpath: Use
mintlify.app as the proxy target. This approach supports any subpath and requires additional routing rules.
Host at /docs subpath
Use this configuration when you want to serve documentation at the /docs path on your domain.
Before configuring your reverse proxy:
- Navigate to Custom domain setup in your dashboard.
- Enable the Host at
/docs toggle.
- Enter your domain and select Add domain.
When you enable Host at /docs, your canonical docs URL becomes <your-subdomain>.mintlify.dev. Cache invalidation stops on mintlify.app, and you must proxy to mintlify.dev for updates to appear.
Routing configuration
Proxy these paths to your Mintlify subdomain:
| Path | Destination | Caching |
|---|
/docs | <your-subdomain>.mintlify.dev/docs | No cache |
/docs/* | <your-subdomain>.mintlify.dev/docs | No cache |
/.well-known/vercel/* | <your-subdomain>.mintlify.dev | No cache |
/.well-known/skills/* (optional) | <your-subdomain>.mintlify.dev/docs | No cache |
/skill.md (optional) | <your-subdomain>.mintlify.dev/docs | No cache |
The /.well-known/skills/* and /skill.md routes are optional. Include them only if you want to serve AI skills files at root paths like your-domain.com/skills.md instead of under your docs subpath like your-domain.com/docs/skills.md.
Configure your reverse proxy with these header requirements:
- Origin: Contains the target subdomain
<your-subdomain>.mintlify.dev
- X-Forwarded-For: Preserves client IP information
- X-Forwarded-Proto: Preserves original protocol (http/https)
- X-Real-IP: Forwards the real client IP address
- User-Agent: Forwards the user agent
Ensure that the Host header is not forwarded.
Example nginx configuration
server {
listen 80;
server_name <your-domain>.com;
# Vercel verification paths
location ~ ^/\.well-known/vercel/ {
proxy_pass https://<your-subdomain>.mintlify.dev;
proxy_set_header Origin <your-subdomain>.mintlify.dev;
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_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# AI skills paths
location ^~ /.well-known/skills/ {
proxy_pass https://<your-subdomain>.mintlify.dev/docs;
proxy_set_header Origin <your-subdomain>.mintlify.dev;
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_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Skill manifest (optional)
location = /skill.md {
proxy_pass https://<your-subdomain>.mintlify.dev/docs;
proxy_set_header Origin <your-subdomain>.mintlify.dev;
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_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Documentation root
location = /docs {
proxy_pass https://<your-subdomain>.mintlify.dev/docs;
proxy_set_header Origin <your-subdomain>.mintlify.dev;
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_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# All documentation paths
location /docs/ {
proxy_pass https://<your-subdomain>.mintlify.dev/docs/;
proxy_set_header Origin <your-subdomain>.mintlify.dev;
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_set_header User-Agent $http_user_agent;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
Custom subpath
When you need a subpath other than /docs (such as /help or /resources), use the following routing configuration.
Proxy these paths to your Mintlify subdomain with the specified caching policies:
| Path | Destination | Caching |
|---|
/.well-known/vercel/* | <your-subdomain>.mintlify.app | No cache |
/.well-known/skills/* | <your-subdomain>.mintlify.app | No cache |
/skill.md | <your-subdomain>.mintlify.app | No cache |
/mintlify-assets/_next/static/* | <your-subdomain>.mintlify.app | Cache enabled |
/_mintlify/* | <your-subdomain>.mintlify.app | No cache |
/* | <your-subdomain>.mintlify.app | No cache |
/ | <your-subdomain>.mintlify.app | No cache |
Configure your reverse proxy with these header requirements:
- Origin: Contains the target subdomain
<your-subdomain>.mintlify.app
- X-Forwarded-For: Preserves client IP information
- X-Forwarded-Proto: Preserves original protocol (HTTP/HTTPS)
- X-Real-IP: Forwards the real client IP address
- User-Agent: Forwards the user agent
Ensure that the Host header is not forwarded
Example nginx configuration
server {
listen 80;
server_name <your-domain>.com;
# Vercel verification paths
location ~ ^/\.well-known/vercel/ {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for verification paths
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# AI skills paths
location ^~ /.well-known/skills/ {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for verification paths
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Skill manifest
location = /skill.md {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for skill manifest
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Static assets with caching
location ~ ^/mintlify-assets/_next/static/ {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Enable caching for static assets
add_header Cache-Control "public, max-age=86400";
}
# Mintlify-specific paths
location ~ ^/_mintlify/ {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for Mintlify paths
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Root path
location = / {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for dynamic content
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# All other documentation paths
location / {
proxy_pass https://<your-subdomain>.mintlify.app;
proxy_set_header Origin <your-subdomain>.mintlify.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-Proto $scheme;
proxy_set_header User-Agent $http_user_agent;
# Disable caching for dynamic content
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
Troubleshooting
Changes not appearing
Symptoms: You publish documentation updates, but the changes don’t appear on your site.
Cause: You have Host at /docs enabled in your dashboard but your reverse proxy points to mintlify.app instead of mintlify.dev.
Solution: Update your reverse proxy configuration to point to <your-subdomain>.mintlify.dev instead of <your-subdomain>.mintlify.app.
404 error
Symptoms: Documentation loads, but features don’t work. API calls fail.
Cause: The reverse proxy forwards the Host header or the Origin header is missing.
Solution:
- Remove
Host header forwarding
- Set
Origin header to your Mintlify subdomain (mintlify.dev for a /docs subpath or mintlify.app for a different subpath)
Symptoms: Slow page loads and layout shifts.
Cause: Incorrect caching configuration.
Solution: For custom subpath configurations, enable caching only for /mintlify-assets/_next/static/* paths. The /docs subpath configuration handles caching automatically.