Cloudflare を使用して yoursite.com/docs のようなカスタムサブパスでドキュメントをホストするには、Cloudflare Workers を作成して設定する必要があります。
開始する前に、Cloudflare アカウントとドメイン名(Cloudflare 管理下か否かは問いません)が必要です。

リポジトリ構成

ドキュメントファイルは、選択したサブパス構成に合わせてリポジトリ内で整理する必要があります。たとえば、ドキュメントを yoursite.com/docs に配置したい場合は、すべてのドキュメントファイルを含む docs/ ディレクトリを作成します。

Cloudflare Worker をセットアップする

まだの方は、Cloudflare Workers のはじめかたガイドに従って Cloudflare Worker を作成してください。
DNS プロバイダーが Cloudflare の場合、CNAME レコードでプロキシを有効にしないでください。

Vercel デプロイでのプロキシ

Vercel のデプロイで Cloudflare をプロキシとして使用する場合、Vercel のドメイン検証や SSL 証明書のプロビジョニングと競合しないよう、適切に設定する必要があります。 不適切なプロキシ設定は、Vercel が Let’s Encrypt の SSL 証明書をプロビジョニングできなくなり、ドメイン検証の失敗を招く可能性があります。

必要なパスの許可リスト

Cloudflare Worker は、以下の特定パスへのトラフィックをブロックやリダイレクトせずに許可する必要があります:
  • /.well-known/acme-challenge/* - Let’s Encrypt の証明書検証に必要
  • /.well-known/vercel/* - Vercel のドメイン検証に必要
Cloudflare は多くの検証ルールを自動で処理しますが、追加のカスタムルールによって、重要なトラフィックが誤ってブロックされる可能性があります。

ヘッダー転送の要件

Worker の設定で HOST ヘッダーが正しく転送されるようにしてください。ヘッダーが適切に転送されない場合、検証リクエストは失敗します。

ルーティングを設定する

Cloudflare ダッシュボードで Edit Code を選択し、以下のスクリプトを Worker のコードに追加します。Worker の編集方法については Cloudflare のドキュメントを参照してください。
[SUBDOMAIN] は固有のサブドメインに、[YOUR_DOMAIN] はサイトのルート URL に、/docs は必要に応じて任意のサブパスに置き換えてください。
addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  try {
    const urlObject = new URL(request.url);
    
    // リクエストが Vercel の検証パス宛ての場合は、そのまま通す
    if (urlObject.pathname.startsWith('/.well-known/')) {
      return await fetch(request);
    }
    
    // リクエストが docs サブディレクトリ宛ての場合
    if (/^\/docs/.test(urlObject.pathname)) {
      // Mintlify へプロキシする
      const DOCS_URL = "[SUBDOMAIN].mintlify.dev";
      const CUSTOM_URL = "[YOUR_DOMAIN]";

      let url = new URL(request.url);
      url.hostname = DOCS_URL;

      let proxyRequest = new Request(url, request);

      proxyRequest.headers.set("Host", DOCS_URL);
      proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
      proxyRequest.headers.set("X-Forwarded-Proto", "https");
      // Vercel へデプロイする場合、クライアント IP を保持
      proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));

      return await fetch(proxyRequest);
    }
  } catch (error) {
    // 該当する処理がない場合は通常のリクエストとして処理
    return await fetch(request);
  }
}
Deploy を選択し、変更が反映されるまで待ちます。
DNS を設定すると、カスタムサブドメインは通常、数分で利用可能になります。DNS の伝播には 1~4 時間かかることがあり、まれに最大で 48 時間かかる場合もあります。サブドメインがすぐに利用できない場合は、トラブルシューティングに進む前にしばらくお待ちください。

Worker をテストする

コードをデプロイしたら、Worker が Mintlify のドキュメントに正しくルーティングするかテストします。
  1. Worker のプレビュー URL を使ってテストします: your-worker.your-subdomain.workers.dev/docs
  2. Worker が Mintlify のドキュメントと自社サイトにルーティングされることを確認します。

カスタムドメインを追加する

  1. Cloudflare ダッシュボードで、対象の Worker に移動します。
  2. Settings > Domains & Routes > Add > Custom Domain を開きます。
  3. ドメインを追加します。
www. あり/なしの両方でドメインを追加することをおすすめします。
詳しくは、Cloudflare のドキュメント「Add a custom domain」をご覧ください。

DNS の競合を解消する

ドメインが既に別のサービスを指している場合は、既存の DNS レコードを削除する必要があります。Cloudflare Workers は、ドメインの全トラフィックを制御するように構成する必要があります。
  1. ドメインの既存の DNS レコードを削除します。詳しくは Cloudflare ドキュメントの「Delete DNS records」を参照してください。
  2. Workers に戻り、カスタムドメインを追加します。

Webflow のカスタムルーティング

メインサイトのホスティングに Webflow を使用しており、同一ドメインの /docs で Mintlify のドキュメントを提供したい場合は、Cloudflare Workers でカスタムルーティングを設定し、ドキュメント以外のすべてのトラフィックをメインサイトへプロキシする必要があります。
この Worker をデプロイする前に、必ずメインサイトをランディングページで運用できるよう設定してください。そうしないと、メインサイトの訪問者にエラーが表示されます。
  1. Webflow で、メインサイト用のランディングページ(例: landing.yoursite.com)を作成します。これは訪問者がサイトにアクセスした際に表示されるページです。
  2. メインサイトをそのランディングページにデプロイします。これにより、Worker を設定している間もメインサイトへ引き続きアクセスできます。
  3. 競合を避けるため、メインサイト内の絶対 URL を相対 URL に更新します。
  4. Cloudflare で Edit Code を選択し、以下のスクリプトを Worker のコードに追加します。
[SUBDOMAIN] は固有のサブドメイン、[YOUR_DOMAIN] はサイトのベース URL、[LANDING_DOMAIN] はランディングページの URL、/docs は必要に応じて変更するサブパスに置き換えてください。
  addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request));
  });
  async function handleRequest(request) {
  try {
    const urlObject = new URL(request.url);
    
    // If the request is to a Vercel verification path, allow it to pass through
    if (urlObject.pathname.startsWith('/.well-known/')) {
      return await fetch(request);
    }
    
    // If the request is to the docs subdirectory
    if (/^\/docs/.test(urlObject.pathname)) {
      // Proxy to Mintlify
      const DOCS_URL = "[SUBDOMAIN].mintlify.dev";
      const CUSTOM_URL = "[YOUR_DOMAIN]";
      let url = new URL(request.url);
      url.hostname = DOCS_URL;
      let proxyRequest = new Request(url, request);
      proxyRequest.headers.set("Host", DOCS_URL);
      proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
      proxyRequest.headers.set("X-Forwarded-Proto", "https");
      // If deploying to Vercel, preserve client IP
      proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
      return await fetch(proxyRequest);
    }
    // Route everything else to main site
    const MAIN_SITE_URL = "[LANDING_DOMAIN]";
    if (MAIN_SITE_URL && MAIN_SITE_URL !== "[LANDING_DOMAIN]") {
      let mainSiteUrl = new URL(request.url);
      mainSiteUrl.hostname = MAIN_SITE_URL;
      return await fetch(mainSiteUrl, {
        method: request.method,
        headers: request.headers,
        body: request.body
      });
    }
  } catch (error) {
    // If no action found, serve the regular request
    return await fetch(request);
  }
  }
  1. Deploy を選択し、変更が反映されるまで待ちます。
DNS を設定すると、カスタムサブドメインは通常、数分で利用可能になります。DNS の伝播には 1~4 時間かかることがあり、まれに最大で 48 時間かかる場合もあります。サブドメインがすぐに利用できない場合は、トラブルシューティングに進む前にしばらくお待ちください。