For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
预约演示登录免费开始
  • 入门
    • 概览
    • 工作原理
    • 快速开始
    • 项目结构
    • Customer showcase
    • 变更日志
  • 配置
    • 概览
    • 站点级设置
    • 页面级设置
  • 编写内容
    • Markdown 基础
    • Markdown 中的富媒体
    • Fern 编辑器
    • 可复用代码片段
  • AI 功能
    • 概览
    • Fern Writer
    • AI 生成的示例
    • Markdown 访问
      • 概览
      • Agent 指令
      • 智能体指令
      • 分析与集成
    • MCP 服务器
    • API 目录发现
      • 概览
      • 工作原理
      • 快速开始
      • 自助设置
      • 项目结构
  • Public API
    • GETJWT from Fern API key
    • GETAlgolia search credentials
    • GETCurrent user information
  • Fern Writer API
    • GETGet Fern Writer Install Link
Checking status...
SOC2Soc 2 Type II
© 2026 Fern • Birch Solutions, Inc., a Postman company

Documentation

SDKsDocsAsk FernCLI Reference

API Definitions

OpenAPIAsyncAPIOpenRPCgRPC

Resources

BlogSupportPricing

Company

Brand KitPrivacy PolicyTerms of Service
LogoLogo
预约演示登录免费开始
在本页
  • How it works
  • Set up your provider
  • Verify your setup
入门

Reverse proxy setup

||以 Markdown 格式查看|
此页面是否有帮助?
在仪表板中编辑
上一个

配置自定义域名

下一个

多源文档

When you host Fern docs on a subpath like mydomain.com/docs, your infrastructure must proxy requests from that path to Fern’s origin. Subdomain setups (docs.mydomain.com) use a CNAME record instead and don’t require a reverse proxy.

How it works

A working reverse proxy does two things:

  1. Routes requests from your subpath to Fern’s origin at app.buildwithfern.com, preserving the original path. The x-fern-host header tells Fern which docs site to serve.
  2. Disables caching of HTML responses so visitors always receive the current deployment.

Every proxied request needs two headers:

HeaderValuePurpose
x-fern-hostYour bare domain without the subpath (e.g. mydomain.com, not mydomain.com/docs)Tells Fern which docs site to serve
Hostapp.buildwithfern.comRoutes the request to Fern’s origin

Fern sets Cache-Control: public, max-age=0, must-revalidate on HTML responses, which most providers respect by default. If yours overrides origin cache headers or applies its own time-to-live, explicitly disable caching for the proxied path.

Don’t cache HTML responses from Fern. Cached HTML references JavaScript and CSS from older deployments — those files no longer exist, so pages fail to load. Static assets (/_next/static/*) are served directly by Fern’s CDN and don’t pass through your proxy.

Set up your provider

Cloudflare Workers
1

Create the Worker

Create a Cloudflare Worker that intercepts requests to your docs subpath and proxies them to Fern:

1const SUBPATH = "/docs";
2const FERN_HOST = "mydomain.com";
3
4export default {
5 async fetch(request) {
6 const url = new URL(request.url);
7
8 if (
9 url.pathname !== SUBPATH &&
10 !url.pathname.startsWith(`${SUBPATH}/`)
11 ) {
12 return new Response("Not found", { status: 404 });
13 }
14
15 const upstreamUrl = new URL(request.url);
16 upstreamUrl.protocol = "https:";
17 upstreamUrl.hostname = "app.buildwithfern.com";
18 upstreamUrl.port = "";
19
20 const proxiedRequest = new Request(upstreamUrl, request);
21 proxiedRequest.headers.set("x-fern-host", FERN_HOST);
22
23 return fetch(proxiedRequest);
24 },
25};

Replace SUBPATH and FERN_HOST with your subpath and bare domain.

2

Attach the Worker to a route

In the Cloudflare dashboard under Workers Routes, attach the Worker to a route pattern like mydomain.com/docs/*.

3

Check for conflicting cache rules

The Worker forwards Fern’s Cache-Control header, so caching works automatically. In the Cloudflare dashboard, confirm that no Page Rule or Cache Rule sets “Cache Level: Cache Everything” for /docs* — if one exists, remove it or override it with “Cache Level: Bypass.”

AWS CloudFront
1

Add a Fern origin

In your CloudFront distribution, go to Origins and create a new origin:

SettingValue
Origin domainapp.buildwithfern.com
ProtocolHTTPS only
HTTPS port443
Minimum origin SSL protocolTLSv1.2

Under Add custom header, add:

Header nameValue
x-fern-hostmydomain.com

Replace mydomain.com with your bare domain (without the subpath).

2

Create a cache behavior for your docs path

Go to Behaviors and create a new behavior:

SettingValue
Path pattern/docs*
OriginThe Fern origin you just created
Viewer protocol policyRedirect HTTP to HTTPS
Cache policyCachingDisabled (AWS managed)
Origin request policyAllViewerExceptHostHeader (AWS managed)

AllViewerExceptHostHeader forwards all viewer headers, query strings, and cookies to the origin while letting CloudFront set the Host header to app.buildwithfern.com. This is required — Fern’s origin uses the Host header for routing and rejects requests with an unrecognized host.

Do not use the AllViewer origin request policy. It forwards the viewer’s Host header (your domain) instead of the origin’s, which causes Fern’s origin to return errors or raw React Server Component payloads instead of HTML.

3

Verify the behavior order

CloudFront evaluates behaviors in order. Ensure your /docs* behavior appears above the default (*) behavior so docs requests are routed to Fern’s origin rather than your primary site.

CloudFront ignores CDN-Cache-Control and Surrogate-Control — only the standard Cache-Control header is read. If you use a custom cache policy instead of CachingDisabled, set the default, minimum, and maximum TTL to 0. A non-zero default TTL caches HTML responses regardless of Fern’s Cache-Control: max-age=0 directive, which can cause stale content and errors.

Netlify
1

Add a rewrite rule

In netlify.toml (or _redirects):

netlify.toml
1[[redirects]]
2 from = "/docs/*"
3 to = "https://app.buildwithfern.com/docs/:splat"
4 status = 200
5 force = true
6
7 [redirects.headers]
8 x-fern-host = "mydomain.com"

Netlify rewrites with status = 200 act as a reverse proxy — the visitor’s browser sees your domain while the content comes from Fern. Netlify respects the origin’s Cache-Control header, so no extra caching configuration is needed.

Vercel
1

Add a route with a transform

Use a route with a transform rule to rewrite the path and set x-fern-host in one step:

vercel.json
1{
2 "$schema": "https://openapi.vercel.sh/vercel.json",
3 "routes": [
4 {
5 "src": "/docs(/.*)?",
6 "dest": "https://app.buildwithfern.com/docs$1",
7 "transforms": [
8 {
9 "type": "request.headers",
10 "op": "set",
11 "target": { "key": "x-fern-host" },
12 "args": "mydomain.com"
13 }
14 ]
15 }
16 ]
17}

Vercel respects the origin’s Cache-Control header for rewrite destinations, so no extra caching configuration is needed.

Nginx
1

Add a location block

1location /docs {
2 proxy_pass https://app.buildwithfern.com;
3 proxy_set_header Host app.buildwithfern.com;
4 proxy_set_header x-fern-host mydomain.com;
5 proxy_set_header X-Real-IP $remote_addr;
6 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
7 proxy_set_header X-Forwarded-Proto $scheme;
8 proxy_ssl_server_name on;
9
10 # Prevent encoding issues with Brotli responses
11 proxy_set_header Accept-Encoding "gzip, deflate";
12
13 # Do not cache HTML
14 proxy_no_cache 1;
15 proxy_cache_bypass 1;
16 add_header Cache-Control "public, max-age=0, must-revalidate" always;
17}

Nginx doesn’t natively support Brotli decompression. The Accept-Encoding override above prevents HTTP/2 transfer errors caused by Fern’s default Brotli-compressed responses.

Akamai
1

Add a routing rule

In a Site Delivery or Ion property, add a rule matching path /docs*:

  • Origin Server: app.buildwithfern.com
  • Forward Host Header: Origin Hostname

Add a Modify Outgoing Request Header behavior:

ActionHeader nameValue
Addx-fern-hostmydomain.com
2

Disable caching on the rule

Add a Caching behavior to the same rule:

SettingValue
Caching OptionNo Store

Alternatively, set Honor Origin Cache-Control to Yes so Akamai respects Fern’s Cache-Control: public, max-age=0, must-revalidate header.

Caddy
1

Add to your Caddyfile

1mydomain.com {
2 handle /docs* {
3 reverse_proxy https://app.buildwithfern.com {
4 header_up Host app.buildwithfern.com
5 header_up x-fern-host mydomain.com
6 }
7 }
8}

Caddy doesn’t cache responses by default, so no extra caching configuration is needed unless you’ve explicitly enabled caching with a cache directive or external module.

Verify your setup

Run these checks against your live subpath:

$# Confirm the page returns HTML (not an error or RSC payload)
$curl -sI https://mydomain.com/docs | grep -i content-type
$# Expected: content-type: text/html; charset=utf-8
$
$# Verify Cache-Control on the HTML response
$curl -sI https://mydomain.com/docs | grep -i cache-control
$# Expected: cache-control: public, max-age=0, must-revalidate
$
$# Verify the page is not cached by your proxy (age should be 0 or absent)
$curl -sI https://mydomain.com/docs | grep -i "^age:"

If content-type is text/x-component instead of text/html, your proxy is forwarding the viewer’s Host header to Fern’s origin. Ensure the Host header sent to the origin is app.buildwithfern.com.

If the age header is present and non-zero, your proxy is serving a cached response. Revisit your provider’s configuration to ensure HTML caching is disabled.