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

# Vercel

> 使用 Vercel 在自定义子路径下托管文档

export const VercelJsonGenerator = () => {
  const [subdomain, setSubdomain] = useState('[SUBDOMAIN]');
  const [subdirectory, setSubdirectory] = useState('docs');
  const vercelConfig = {
    rewrites: [{
      source: "/_mintlify/api/request",
      destination: `https://${subdomain}.mintlify.app/_mintlify/api/request`
    }, {
      source: "/api/request",
      destination: `https://${subdomain}.mintlify.app/_mintlify/api/request`
    }, {
      source: `/${subdirectory}`,
      destination: `https://${subdomain}.mintlify.app`
    }, {
      source: `/${subdirectory}/llms.txt`,
      destination: `https://${subdomain}.mintlify.app/llms.txt`
    }, {
      source: `/${subdirectory}/llms-full.txt`,
      destination: `https://${subdomain}.mintlify.app/llms-full.txt`
    }, {
      source: `/${subdirectory}/sitemap.xml`,
      destination: `https://${subdomain}.mintlify.app/sitemap.xml`
    }, {
      source: `/${subdirectory}/robots.txt`,
      destination: `https://${subdomain}.mintlify.app/robots.txt`
    }, {
      source: `/${subdirectory}/:path*`,
      destination: `https://${subdomain}.mintlify.app/${subdirectory}/:path*`
    }, {
      source: "/mintlify-assets/:path+",
      destination: `https://${subdomain}.mintlify.app/mintlify-assets/:path+`
    }]
  };
  const copyToClipboard = () => {
    navigator.clipboard.writeText(JSON.stringify(vercelConfig, null, 2)).then(() => {
      console.log('Copied config to clipboard!');
    }).catch(err => {
      console.error("Failed to copy: ", err);
    });
  };
  return <div className="p-4 border dark:border-white/10 rounded-2xl not-prose space-y-4">
      <div className="space-y-4">
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">
            Subdomain
          </label>
          <input type="text" value={subdomain} onChange={e => setSubdomain(e.target.value)} placeholder="your-subdomain" className="w-full p-1 text-sm rounded border dark:border-white/10 bg-transparent" />
        </div>
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">
            Subdirectory
          </label>
          <input type="text" value={subdirectory} onChange={e => setSubdirectory(e.target.value)} placeholder="docs" className="w-full p-1 text-sm rounded border dark:border-white/10 bg-transparent" />
        </div>
      </div>
      <div className="relative">
        <button onClick={copyToClipboard} className="absolute top-2 right-2 p-2 rounded-lg transition-all duration-200 group">
          <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 dark:text-white/60 text-gray-400 group-hover:text-gray-500 dark:group-hover:text-white/60 transition-colors">
            <path d="M14.25 5.25H7.25C6.14543 5.25 5.25 6.14543 5.25 7.25V14.25C5.25 15.3546 6.14543 16.25 7.25 16.25H14.25C15.3546 16.25 16.25 15.3546 16.25 14.25V7.25C16.25 6.14543 15.3546 5.25 14.25 5.25Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"></path>
            <path d="M2.80103 11.998L1.77203 5.07397C1.61003 3.98097 2.36403 2.96397 3.45603 2.80197L10.38 1.77297C11.313 1.63397 12.19 2.16297 12.528 3.00097" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"></path>
          </svg>
          <span className="absolute top-9 left-1/2 transform -translate-x-1/2 bg-primary text-white text-xs px-1.5 py-0.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap">
            Copy
          </span>
        </button>
        <pre className="p-4 rounded-lg overflow-auto text-xs border dark:border-white/10">
          <code>{JSON.stringify(vercelConfig, null, 2)}</code>
        </pre>
      </div>
    </div>;
};

<div id="verceljson-file">
  ## vercel.json 文件
</div>

`vercel.json` 文件用于配置项目的构建与部署。它位于项目根目录，控制部署的多个方面，包括路由、重写、重定向、请求头，以及构建设置。

我们使用 `rewrites` 配置将来自主域名的请求代理到文档站点。

Rewrites 会在不更改浏览器中 URL 的情况下，将传入请求映射到不同的目标。当有人访问 `yoursite.com/docs` 时，Vercel 会在内部从 `your-subdomain.mintlify.dev/docs` 获取内容，但用户在浏览器中仍会看到 `yoursite.com/docs`。这与重定向不同，重定向会将用户带到完全不同的 URL。

你可以将子路径自定义为任意你喜欢的值，例如 `/docs`、`/help` 或 `/guides`。此外，你也可以使用更深层级的嵌套子路径，例如 `/product/docs`。

<div id="repository-structure">
  ## 存储库结构
</div>

必须在存储库中按照所选子路径结构组织文档文件。举例来说，如果希望文档位于 `yoursite.com/docs`，则应创建一个包含所有文档文件的 `docs/` 目录。

<div id="configuration">
  ## 配置
</div>

要在 Vercel 上将文档托管到自定义子路径下，请在 `vercel.json` 文件中添加以下配置。此示例使用 `/docs`，你也可以替换为任意子路径：

```json theme={null}
{
  "rewrites": [
    {
      "source": "/docs",
      "destination": "https://[subdomain].mintlify.dev/docs"
    },
    {
      "source": "/docs/:match*",
      "destination": "https://[subdomain].mintlify.dev/docs/:match*"
    }
  ]
}
```

* **`source`**: 你的 domain 上用于触发重写的路径模式。
* **`destination`**: 请求应被代理到的目标位置。
* **`:match*`**: 一个通配符，用于捕获子路径之后的所有路径段。

更多信息请参见 Vercel 文档中的[使用 vercel.json 配置项目：Rewrites](https://vercel.com/docs/projects/project-configuration#rewrites)。

<div id="generate-rewrites">
  ### 生成重写规则
</div>

输入你的子域和自定义子目录，为你的 `vercel.json` 文件生成重写规则。

<VercelJsonGenerator />

<div id="using-external-proxies-with-vercel">
  ## 在 Vercel 中使用外部代理
</div>

如果你在 Vercel 部署前面使用外部代理（如 Cloudflare 或 AWS CloudFront），必须正确配置，避免与 Vercel 的 domain 验证和 SSL 证书签发发生冲突。

错误的代理配置可能会阻止 Vercel 为你配置 Let's Encrypt SSL 证书，并导致 domain 验证失败。

请参阅 Vercel 文档中的[受支持的提供商](https://vercel.com/guides/how-to-setup-verified-proxy#supported-providers-verified-proxy-lite)。

<div id="required-path-allowlist">
  ### 必需的路径允许列表
</div>

你的外部代理必须允许以下特定路径的流量通过，且不得阻止、重定向或进行强缓存：

* `/.well-known/acme-challenge/*` - 用于 Let's Encrypt 证书验证
* `/.well-known/vercel/*` - 用于 Vercel domain 验证
* `/mintlify-assets/_next/static/*` - 用于静态资源

这些路径应原样直接透传到你的 Vercel 部署。

<div id="header-forwarding-requirements">
  ### 头部转发要求
</div>

确保你的代理正确转发 `HOST` 头部。若未正确转发该头部，验证请求将会失败。

<div id="testing-your-proxy-setup">
  ### 测试你的代理设置
</div>

要验证代理是否已正确配置：

1. 测试 `https://[yourdomain].com/.well-known/vercel/` 是否能返回响应。
2. 确认在你的 Vercel 控制台中已正确签发 SSL 证书。
3. 检查 domain 验证是否已成功完成。
