import { jsx, jsxs, Fragment } from 'solid-jsx/jsx-runtime';

/*@jsxRuntime automatic @jsxImportSource solid-jsx*/
const toc = [{
  "depth": 1,
  "value": "サーバーサイドレンダリング",
  "children": [{
    "depth": 2,
    "value": "ハイドレーションスクリプト",
    "children": []
  }, {
    "depth": 2,
    "value": "非同期およびストリーミング SSR",
    "children": []
  }, {
    "depth": 2,
    "value": "SSR の注意点",
    "children": []
  }, {
    "depth": 2,
    "value": "SSR を始める",
    "children": []
  }, {
    "depth": 2,
    "value": "静的サイト生成を始める",
    "children": []
  }]
}];
function _createMdxContent(props) {
  const _components = Object.assign({
    h1: "h1",
    a: "a",
    p: "p",
    code: "code",
    pre: "pre",
    span: "span",
    em: "em",
    h2: "h2",
    ul: "ul",
    li: "li"
  }, props.components);
  return jsxs(Fragment, {
    children: [jsxs(_components.h1, {
      id: "サーバーサイドレンダリング",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#サーバーサイドレンダリング",
        children: "#"
      }), "サーバーサイドレンダリング"]
    }), "\n", jsxs(_components.p, {
      children: ["Solid は、JSX テンプレートを超効率的な文字列付加コードにコンパイルすることで、サーバーレンダリングを処理します。これは、babel プラグインまたはプリセットで、", jsx(_components.code, {
        children: "generate: \"ssr\""
      }), " を渡すことで実現できます。クライアントとサーバーの両方で、ハイドレーションに対応したコードを生成するには、", jsx(_components.code, {
        children: "hydratable: true"
      }), " を渡す必要があります。"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "solid-js"
      }), " と ", jsx(_components.code, {
        children: "solid-js/web"
      }), " のランタイムは、node 環境で実行する場合には、非リアクティブな対照物と交換されます。他の環境では、", jsx(_components.code, {
        children: "node"
      }), " に設定された条件付きエクスポートでサーバーコードをバンドルする必要があります。ほとんどのバンドルツールは、これを行なう方法を持っています。一般的には、エクスポート条件として ", jsx(_components.code, {
        children: "solid"
      }), " を使用することをお勧めします。また、ライブラリは ", jsx(_components.code, {
        children: "solid"
      }), " エクスポートでソースを出荷することをお勧めします。"]
    }), "\n", jsxs(_components.p, {
      children: ["SSR 用にビルドすると、2 つの別々のバンドルを生成することになるので、若干の設定が必要になります。クライアントのエントリーでは ", jsx(_components.code, {
        children: "hydrate"
      }), " を使用します:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { hydrate } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "hydrate"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ", ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ");\n"]
      })
    }), "\n", jsx(_components.p, {
      children: jsx(_components.em, {
        children: "注意: ドキュメントルートからレンダリングとハイドレーションを行うことが可能です。これにより、JSX ですべてのビューを記述できます。"
      })
    }), "\n", jsx(_components.p, {
      children: "サーバーのエントリーでは、Solid が提供する 4 つのレンダリングオプションのいずれかを使用できます。それぞれ、出力とドキュメントの先頭に挿入されるスクリプトタグが生成されます。"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " {\n  renderToString,\n  renderToStringAsync,\n  renderToStream,\n} ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 同期文字列レンダリング"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " html = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "renderToString"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ");\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 非同期文字列レンダリング"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " html = ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "renderToStringAsync"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ");\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ストリームレンダリング"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " stream = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "renderToStream"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ");\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// Node"
        }), "\nstream.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "pipe"
        }), "(res);\n\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "// Web ストリーム（Cloudflare Workers など）"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " { readable, writable } = ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "TransformStream"
        }), "();\nstream.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "pipeTo"
        }), "(writable);\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["便利なように ", jsx(_components.code, {
        children: "solid-js/web"
      }), " は ", jsx(_components.code, {
        children: "isServer"
      }), " フラグをエクスポートします。これは、ほとんどのバンドラーが、このフラグを持つものをツリーシェイクしたり、このフラグを持つコードでのみ使用されるものをクライアントバンドルからインポートしたりできるので便利です。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { isServer } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "if"
        }), " (isServer) {\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// サーバーでのみ実行"
        }), "\n} ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "else"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ブラウザでのみ実行"
        }), "\n}\n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "ハイドレーションスクリプト",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#ハイドレーションスクリプト",
        children: "#"
      }), "ハイドレーションスクリプト"]
    }), "\n", jsxs(_components.p, {
      children: ["Solid のランタイムがロードされる前から徐々にハイドレーションさせるためには、特別なスクリプトをページに挿入する必要があります。このスクリプトは、", jsx(_components.code, {
        children: "generateHydrationScript"
      }), " で生成して挿入するか、", jsx(_components.code, {
        children: "<HydrationScript />"
      }), " タグを使用して JSX の一部として含めることができます。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { generateHydrationScript } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " app = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "renderToString"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "App"
            }), " />"]
          })
        }), ");\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " html = ", jsxs(_components.span, {
          className: "hljs-string",
          children: ["`\n  <html lang=\"en\">\n    <head>\n      <title>🔥 Solid SSR 🔥</title>\n      <meta charset=\"UTF-8\" />\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n      <link rel=\"stylesheet\" href=\"/styles.css\" />\n      ", jsx(_components.span, {
            className: "hljs-subst",
            children: "${generateHydrationScript()}"
          }), "\n    </head>\n    <body>", jsx(_components.span, {
            className: "hljs-subst",
            children: "${app}"
          }), "</body>\n  </html>\n`"]
        }), ";\n"]
      })
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "HydrationScript"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "App"
        }), " = (", jsx(_components.span, {
          className: "hljs-params"
        }), ") => {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " (\n    ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "html"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "lang"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"en\""
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "head"
            }), ">"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "title"
            }), ">"]
          }), "🔥 Solid SSR 🔥", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "title"
            }), ">"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "meta"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "charset"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"UTF-8\""
            }), " />"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "meta"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "name"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"viewport\""
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "content"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"width=device-width, initial-scale=1.0\""
            }), " />"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "link"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "rel"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"stylesheet\""
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "href"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"/styles.css\""
            }), " />"]
          }), "\n        ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "HydrationScript"
            }), " />"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "head"
            }), ">"]
          }), "\n      ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "body"
            }), ">"]
          }), "{/*... rest of App*/}", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "body"
            }), ">"]
          }), "\n    ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "html"
            }), ">"]
          })]
        }), "\n  );\n};\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["ドキュメントからハイドレーションする場合、クライアントの実行時に利用できないアセットを挿入すると ", jsx(_components.code, {
        children: "<head>"
      }), "タグの下にない場合は問題が発生する可能性があります。Solid は ", jsx(_components.code, {
        children: "<NoHydration>"
      }), " コンポーネントを提供しており、このコンポーネントの子は、サーバー上では通常通り動作しますがブラウザ上ではハイドレーションされません。"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-jsx",
        children: ["<", jsx(_components.span, {
          className: "hljs-title class_",
          children: "NoHydration"
        }), ">\n  ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "ImNotHydrated"
            }), " />"]
          })
        }), "\n</", jsx(_components.span, {
          className: "hljs-title class_",
          children: "NoHydration"
        }), ">\n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "非同期およびストリーミング-ssr",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#非同期およびストリーミング-ssr",
        children: "#"
      }), "非同期およびストリーミング SSR"]
    }), "\n", jsx(_components.p, {
      children: "これらのメカニズムは、アプリケーションの動作に関する Solid の知識に基づいて構築されています。\n先にフェッチしてからレンダリングするのではなく、サーバー上で Suspense と Resource API を使用します。\nSolid は、クライアントと同様に、サーバー上でレンダリングしながらフェッチします。\nコードも全く同じように書かれています。"
    }), "\n", jsx(_components.p, {
      children: "非同期レンダリングは、すべてのサスペンス境界が解決するまで待ってから結果を送信します（静的サイト生成の場合はファイルに書き込みます）。"
    }), "\n", jsx(_components.p, {
      children: "ストリーミングは、同期コンテンツのブラウザへのフラッシュをすぐに開始します。最初は、サーバー上で Suspense フォールバックをレンダリングして、クライアントに送信します。\n次に、サーバー上で非同期データの読み込みが終了すると、データと HTML を同じストリームでクライアントに送ります。\nブラウザはジョブを終了し、Suspense を解決して、フォールバックを実際のコンテンツに置き換えます。"
    }), "\n", jsx(_components.p, {
      children: "この方法の利点:"
    }), "\n", jsxs(_components.ul, {
      children: ["\n", jsx(_components.li, {
        children: "サーバーは非同期データが応答するのを待つ必要がありません。アセットはより早くブラウザにロードされ、ユーザーはより早くコンテンツを見始めることができます。"
      }), "\n", jsx(_components.li, {
        children: "JAMStack のようなクライアントフェッチに比べて、データのロードはサーバー上ですぐに始まり、クライアントの JavaScript がロードされるのを待つ必要はありません。"
      }), "\n", jsx(_components.li, {
        children: "すべてのデータはシリアル化され、サーバーからクライアントに自動的に転送されます。"
      }), "\n"]
    }), "\n", jsxs(_components.h2, {
      id: "ssr-の注意点",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#ssr-の注意点",
        children: "#"
      }), "SSR の注意点"]
    }), "\n", jsx(_components.p, {
      children: "Solid のアイソモーフィック SSR ソリューションは、どちらの環境でも同じように動作する単一のコードベースとしてコードを書くことができるという点で非常に強力です。しかし、これによってハイドレーションに期待されることがあります。ほとんどの場合、クライアントでレンダリングされるビューは、サーバーでレンダリングされるビューと同じです。テキストに関しては正確である必要はありませんが、マークアップは構造的に同じであるべきです。"
    }), "\n", jsx(_components.p, {
      children: "サーバーでレンダリングされたマーカーを使用して、サーバー上の要素やリソースの位置を一致させます。このため、クライアントとサーバーは同じコンポーネントを使用する必要があります。これは、Solid がクライアントとサーバーで同じようにレンダリングされることを考えると、通常は問題になりません。しかし、現在のところ、クライアントではハイドレーションされないものをサーバーでレンダリングする手段がありません。現在のところ、ページ全体を部分的にハイドレーションさせて、ハイドレーションマーカーを生成しない方法はありません。それはオール・オア・ナッシングです。部分的なハイドレーションは、将来的に検討したいと考えています。"
    }), "\n", jsxs(_components.p, {
      children: ["最後に、すべてのリソースは ", jsx(_components.code, {
        children: "render"
      }), " ツリーで定義する必要があります。リソースは自動的にシリアライズされてブラウザに取り込まれますが、これは ", jsx(_components.code, {
        children: "render"
      }), " メソッドがレンダリングの進行状況を把握しているからです。同様に、サーバーにはリアクティビティがないので、最初のレンダリングで Signal を更新して、ツリーの上位に反映されることを期待してはいけません。サスペンスの境界がある一方で、Solid の SSR は基本的にトップダウンです。"]
    }), "\n", jsxs(_components.h2, {
      id: "ssr-を始める",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#ssr-を始める",
        children: "#"
      }), "SSR を始める"]
    }), "\n", jsxs(_components.p, {
      children: ["SSR の設定には注意が必要です。", jsx(_components.a, {
        href: "https://github.com/solidjs/solid/blob/main/packages/solid-ssr",
        children: "solid-ssr"
      }), " パッケージにはいくつかの例があります。"]
    }), "\n", jsxs(_components.p, {
      children: ["しかし、この経験をよりスムーズにすることを目的とした新しいスターター ", jsx(_components.a, {
        href: "https://github.com/solidjs/solid-start",
        children: "SolidStart"
      }), " が開発されています。"]
    }), "\n", jsxs(_components.h2, {
      id: "静的サイト生成を始める",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#静的サイト生成を始める",
        children: "#"
      }), "静的サイト生成を始める"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.a, {
        href: "https://github.com/solidjs/solid/blob/main/packages/solid-ssr",
        children: "solid-ssr"
      }), " には、静的サイトや事前レンダリングされたサイトを生成するためのユーティリティが同梱されています。詳しくは README をご覧ください。"]
    })]
  });
}
function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || ({});
  return MDXLayout ? jsx(MDXLayout, Object.assign({}, props, {
    children: jsx(_createMdxContent, props)
  })) : _createMdxContent(props);
}

export { MDXContent as default, toc };
//# sourceMappingURL=server-b71215c1.js.map
