{"id":2713,"date":"2025-03-24T08:46:44","date_gmt":"2025-03-23T23:46:44","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2713"},"modified":"2025-03-24T08:47:13","modified_gmt":"2025-03-23T23:47:13","slug":"%e3%80%90%e5%ae%8c%e5%85%a8%e3%82%ac%e3%82%a4%e3%83%892024%e3%80%91laravel%e3%81%a8react%e3%81%ae%e6%9c%80%e5%bc%b7%e7%b5%b1%e5%90%88%ef%bc%81%e5%ae%9f%e8%a3%85%e6%89%8b%e9%a0%86%e3%81%a85%e3%81%a4","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2713","title":{"rendered":"\u3010\u5b8c\u5168\u30ac\u30a4\u30c92024\u3011Laravel\u3068React\u306e\u6700\u5f37\u7d71\u5408\uff01\u5b9f\u88c5\u624b\u9806\u30685\u3064\u306e\u91cd\u8981\u30dd\u30a4\u30f3\u30c8"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Laravel\u3068React\u306e\u30e1\u30ea\u30c3\u30c8<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">\u30e2\u30c0\u30f3\u306aSPA\u958b\u767a\u304c\u5b9f\u73fe\u3067\u304d\u308b\u7406\u7531<\/a>      <\/li>      <li>        <a href=\"#i-2\">\u958b\u767a\u52b9\u7387\u304c\u5287\u7684\u306b\u5411\u4e0a\u3059\u308b\u5177\u4f53\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-3\">\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u3068\u4fdd\u5b88\u6027\u306e\u5411\u4e0a\u30dd\u30a4\u30f3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u904b\u7528\u307e\u3067\u306e\u5b9f\u8df5\u7684\u306a\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u306e\u958b\u767a\u74b0\u5883\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-6\">Laravel Breeze\u3068Inertia\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-7\">API\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-8\">\u30bb\u30ad\u30e5\u30a2\u306a\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u69cb\u7bc9\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-9\">Sanctum\u3092\u4f7f\u7528\u3057\u305f\u8a8d\u8a3c\u306e\u5b9f\u73fe<\/a>      <\/li>      <li>        <a href=\"#i-10\">\u30af\u30ed\u30b9\u30ea\u30af\u30a8\u30b9\u30c8\u30b5\u30a4\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\u5bfe\u7b56<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u624b\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u30d0\u30f3\u30c9\u30eb\u30b5\u30a4\u30ba\u306e\u6700\u9069\u5316\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-14\">\u52b9\u7387\u7684\u306aAPI\u901a\u4fe1\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-15\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u8996\u70b9\u3068\u5b9f\u88c5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-16\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u89e3\u6c7a\u7b56<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-17\">\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6a5f\u80fd\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-18\">\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u901a\u4fe1\u306e\u5b9f\u73fe\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-19\">\u8907\u96d1\u306a\u30d5\u30a9\u30fc\u30e0\u51e6\u7406\u306e\u5b9f\u88c5\u624b\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-20\">\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u3068CI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-21\">\u672c\u756a\u74b0\u5883\u306e\u69cb\u7bc9\u624b\u9806<\/a>      <\/li>      <li>        <a href=\"#i-22\">\u81ea\u52d5\u30c6\u30b9\u30c8\u306e\u5c0e\u5165\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-23\">\u7d99\u7d9a\u7684\u306a\u30c7\u30d7\u30ed\u30a4\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Laravel\u3068React\u306e\u30e1\u30ea\u30c3\u30c8<\/h2>\n\n\n\n<p>\u30e2\u30c0\u30f3\u306aWeb\u958b\u767a\u306b\u304a\u3044\u3066\u3001Laravel\u3068React\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u975e\u5e38\u306b\u5f37\u529b\u306a\u9078\u629e\u80a2\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u7d44\u307f\u5408\u308f\u305b\u304c\u3082\u305f\u3089\u3059\u5177\u4f53\u7684\u306a\u30e1\u30ea\u30c3\u30c8\u3068\u3001\u5b9f\u88c5\u306e\u30dd\u30a4\u30f3\u30c8\u306b\u3064\u3044\u3066\u8a73\u3057\u304f\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">\u30e2\u30c0\u30f3\u306aSPA\u958b\u767a\u304c\u5b9f\u73fe\u3067\u304d\u308b\u7406\u7531<\/h3>\n\n\n\n<p>Laravel\u3068React\u306e\u7d71\u5408\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u7279\u5fb4\u3092\u6301\u3064\u30e2\u30c0\u30f3\u306aSingle Page Application (SPA)\u306e\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u660e\u78ba\u306a\u5206\u96e2<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Laravel\u306fRESTful API\u3092\u63d0\u4f9b<\/li>\n\n\n\n<li>React\u306f\u72ec\u7acb\u3057\u305f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u3057\u3066\u52d5\u4f5c<\/li>\n\n\n\n<li>\u5404\u5c64\u306e\u8cac\u52d9\u304c\u660e\u78ba\u3067\u3001\u958b\u767a\u52b9\u7387\u304c\u5411\u4e0a<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u306a\u66f4\u65b0\u3068\u512a\u308c\u305fUX<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ React\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u306e\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u30c7\u30fc\u30bf\u53d6\u5f97\u4f8b\n   const [data, setData] = useState([]);\n\n   useEffect(() =&gt; {\n     const fetchData = async () =&gt; {\n       const response = await axios.get('\/api\/realtime-data');\n       setData(response.data);\n     };\n\n     \/\/ WebSocket\u3092\u4f7f\u7528\u3057\u305f\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u66f4\u65b0\n     Echo.private('data-channel')\n       .listen('DataUpdated', (e) =&gt; {\n         setData(prevData =&gt; [...prevData, e.newData]);\n       });\n\n     fetchData();\n   }, []);<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">\u958b\u767a\u52b9\u7387\u304c\u5287\u7684\u306b\u5411\u4e0a\u3059\u308b\u5177\u4f53\u4f8b<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30d9\u30fc\u30b9\u306e\u958b\u767a<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u518d\u5229\u7528\u53ef\u80fd\u306aUI\u30d1\u30fc\u30c4\u306e\u4f5c\u6210<\/li>\n\n\n\n<li>\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u30c1\u30fc\u30e0\u958b\u767a\u3067\u306e\u4f5c\u696d\u5206\u62c5\u304c\u5bb9\u6613<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ Laravel\u3067\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5bfe\u5fdcAPI\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\n   public function getComponentData(Request $request)\n   {\n       return response()-&gt;json([\n           'data' =&gt; $this-&gt;componentService-&gt;getData(),\n           'meta' =&gt; [\n               'lastUpdated' =&gt; now(),\n               'version' =&gt; config('app.version')\n           ]\n       ]);\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u74b0\u5883\u306e\u7d71\u4e00\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Laravel Mix\u306b\u3088\u308b\u30a2\u30bb\u30c3\u30c8\u7ba1\u7406<\/li>\n\n\n\n<li>\u7d71\u4e00\u3055\u308c\u305f\u30d3\u30eb\u30c9\u30d7\u30ed\u30bb\u30b9<\/li>\n\n\n\n<li>\u958b\u767a\u74b0\u5883\u306eDocker\u30b3\u30f3\u30c6\u30ca\u5316\u304c\u5bb9\u6613<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u3068\u4fdd\u5b88\u6027\u306e\u5411\u4e0a\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3078\u306e\u5bfe\u5fdc<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9API\u306e\u5206\u5272\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u72ec\u7acb\u3057\u305f\u30c7\u30d7\u30ed\u30a4<\/li>\n\n\n\n<li>\u30b9\u30b1\u30fc\u30eb\u30a2\u30a6\u30c8\u304c\u5bb9\u6613<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u52b9\u7387\u7684\u306a\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ Laravel\u3067\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u5b9f\u88c5\u4f8b\n   public function getCachedData()\n   {\n       return Cache::remember('component_data', 3600, function () {\n           return $this-&gt;repository-&gt;getAllData();\n       });\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30fc\u30c9\u54c1\u8cea\u306e\u7dad\u6301<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>TypeScript\u306b\u3088\u308b\u578b\u5b89\u5168\u6027<\/li>\n\n\n\n<li>PHPUnit\u3068Jest\u3067\u306e\u30c6\u30b9\u30c8\u81ea\u52d5\u5316<\/li>\n\n\n\n<li>CI\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u306e\u69cb\u7bc9\u304c\u5bb9\u6613<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306b\u3001Laravel\u3068React\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u3001\u30e2\u30c0\u30f3\u306aWeb\u958b\u767a\u306b\u5fc5\u8981\u306a\u8981\u7d20\u3092\u6e80\u305f\u3057\u306a\u304c\u3089\u3001\u9ad8\u3044\u958b\u767a\u52b9\u7387\u3068\u4fdd\u5b88\u6027\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u5229\u70b9\u3092\u6700\u5927\u9650\u306b\u6d3b\u304b\u3059\u305f\u3081\u306e\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u904b\u7528\u307e\u3067\u306e\u5b9f\u8df5\u7684\u306a\u624b\u9806<\/h2>\n\n\n\n<p>Laravel\u3068React\u3092\u52b9\u679c\u7684\u306b\u7d71\u5408\u3059\u308b\u305f\u3081\u306e\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u904b\u7528\u307e\u3067\u306e\u624b\u9806\u3092\u3001\u5b9f\u8df5\u7684\u306a\u4f8b\u3092\u4ea4\u3048\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u306e\u958b\u767a\u74b0\u5883\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u524d\u63d0\u6761\u4ef6\u306e\u78ba\u8a8d<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP 8.1\u4ee5\u4e0a<\/li>\n\n\n\n<li>Composer 2.x<\/li>\n\n\n\n<li>Node.js 16.x\u4ee5\u4e0a<\/li>\n\n\n\n<li>npm 8.x\u4ee5\u4e0a<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Laravel\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\u3068\u521d\u671f\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   # \u65b0\u898f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\n   composer create-project laravel\/laravel laravel-react-app\n\n   cd laravel-react-app\n\n   # \u5fc5\u8981\u306aPHP\u4f9d\u5b58\u95a2\u4fc2\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   composer require laravel\/sanctum\n   composer require laravel\/breeze --dev<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>React\u74b0\u5883\u306e\u69cb\u7bc9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   # Laravel Breeze\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068react\u306e\u9078\u629e\n   php artisan breeze:install react\n\n   # \u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u4f9d\u5b58\u95a2\u4fc2\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   npm install\n\n   # \u958b\u767a\u30b5\u30fc\u30d0\u30fc\u306e\u8d77\u52d5\n   npm run dev<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">Laravel Breeze\u3068Inertia\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Inertia\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3068\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Kernel.php\n   protected $middlewareGroups = [\n       'web' =&gt; [\n           \/\/ ...\n           \\Illuminate\\Http\\Middleware\\HandleInertiaRequests::class,\n       ],\n   ];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/Layouts\/AppLayout.jsx\n   import React from 'react';\n   import { Head } from '@inertiajs\/react';\n   import Navbar from '@\/Components\/Navbar';\n\n   export default function AppLayout({ title, children }) {\n       return (\n           &lt;&gt;\n               &lt;Head title={title} \/&gt;\n               &lt;div className=\"min-h-screen bg-gray-100\"&gt;\n                   &lt;Navbar \/&gt;\n                   &lt;main className=\"py-12\"&gt;\n                       {children}\n                   &lt;\/main&gt;\n               &lt;\/div&gt;\n           &lt;\/&gt;\n       );\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">API\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>API\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ routes\/api.php\n   Route::middleware('auth:sanctum')-&gt;group(function () {\n       Route::get('\/user', function (Request $request) {\n           return $request-&gt;user();\n       });\n\n       Route::apiResource('posts', PostController::class);\n   });<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u3067\u306e\u30b9\u30c6\u30fc\u30c8\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/store\/useStore.js\n   import create from 'zustand';\n\n   const useStore = create((set) =&gt; ({\n       posts: [],\n       loading: false,\n       error: null,\n\n       fetchPosts: async () =&gt; {\n           set({ loading: true });\n           try {\n               const response = await axios.get('\/api\/posts');\n               set({ posts: response.data, loading: false });\n           } catch (error) {\n               set({ error: error.message, loading: false });\n           }\n       },\n\n       addPost: async (postData) =&gt; {\n           try {\n               const response = await axios.post('\/api\/posts', postData);\n               set((state) =&gt; ({\n                   posts: [...state.posts, response.data]\n               }));\n           } catch (error) {\n               set({ error: error.message });\n           }\n       }\n   }));\n\n   export default useStore;<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u52b9\u7387\u7684\u306aAPI\u901a\u4fe1\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/services\/api.js\n   import axios from 'axios';\n\n   const api = axios.create({\n       baseURL: '\/api',\n       headers: {\n           'X-Requested-With': 'XMLHttpRequest',\n           'Content-Type': 'application\/json'\n       }\n   });\n\n   \/\/ \u30a4\u30f3\u30bf\u30fc\u30bb\u30d7\u30bf\u30fc\u306e\u8a2d\u5b9a\n   api.interceptors.response.use(\n       response =&gt; response,\n       error =&gt; {\n           if (error.response.status === 401) {\n               window.location.href = '\/login';\n           }\n           return Promise.reject(error);\n       }\n   );\n\n   export default api;<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u3068\u5b9f\u88c5\u306b\u3088\u308a\u3001Laravel\u3068React\u3092\u52b9\u679c\u7684\u306b\u7d71\u5408\u3057\u3001\u30e2\u30c0\u30f3\u306a\u958b\u767a\u74b0\u5883\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u7279\u306b\u91cd\u8981\u306a\u306e\u306f\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u660e\u78ba\u306a\u8cac\u52d9\u5206\u96e2\u3092\u7dad\u6301\u3057\u306a\u304c\u3089\u3001\u52b9\u7387\u7684\u306a\u958b\u767a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u78ba\u7acb\u3059\u308b\u3053\u3068\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-8\">\u30bb\u30ad\u30e5\u30a2\u306a\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u69cb\u7bc9\u65b9\u6cd5<\/h2>\n\n\n\n<p>Laravel\u3068React\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u74b0\u5883\u3067\u3001\u30bb\u30ad\u30e5\u30a2\u306a\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u3092\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8a73\u3057\u304f\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">Sanctum\u3092\u4f7f\u7528\u3057\u305f\u8a8d\u8a3c\u306e\u5b9f\u73fe<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Sanctum\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ config\/sanctum.php\n   return [\n       'stateful' =&gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(\n           '%s%s',\n           'localhost,localhost:3000,localhost:8080,127.0.0.1,127.0.0.1:8000,::1',\n           env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''\n       ))),\n\n       'guard' =&gt; ['web'],\n       'expiration' =&gt; null,\n       'middleware' =&gt; [\n           'verify_csrf_token' =&gt; App\\Http\\Middleware\\VerifyCsrfToken::class,\n           'encrypt_cookies' =&gt; App\\Http\\Middleware\\EncryptCookies::class,\n       ],\n   ];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Controllers\/Auth\/AuthController.php\n   namespace App\\Http\\Controllers\\Auth;\n\n   use App\\Http\\Controllers\\Controller;\n   use Illuminate\\Http\\Request;\n   use Illuminate\\Support\\Facades\\Auth;\n\n   class AuthController extends Controller\n   {\n       public function login(Request $request)\n       {\n           $credentials = $request-&gt;validate([\n               'email' =&gt; ['required', 'email'],\n               'password' =&gt; ['required'],\n           ]);\n\n           if (Auth::attempt($credentials)) {\n               $request-&gt;session()-&gt;regenerate();\n\n               return response()-&gt;json([\n                   'user' =&gt; Auth::user(),\n                   'message' =&gt; '\u8a8d\u8a3c\u306b\u6210\u529f\u3057\u307e\u3057\u305f'\n               ]);\n           }\n\n           return response()-&gt;json([\n               'message' =&gt; '\u8a8d\u8a3c\u60c5\u5831\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093'\n           ], 401);\n       }\n\n       public function logout(Request $request)\n       {\n           Auth::guard('web')-&gt;logout();\n           $request-&gt;session()-&gt;invalidate();\n           $request-&gt;session()-&gt;regenerateToken();\n\n           return response()-&gt;json(['message' =&gt; '\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f']);\n       }\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u30af\u30ed\u30b9\u30ea\u30af\u30a8\u30b9\u30c8\u30b5\u30a4\u30c8\u30d5\u30a9\u30fc\u30b8\u30a7\u30ea\u5bfe\u7b56<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>CSRF\u30c8\u30fc\u30af\u30f3\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/utils\/axios-config.js\n   import axios from 'axios';\n\n   \/\/ CSRF\u30c8\u30fc\u30af\u30f3\u306e\u8a2d\u5b9a\n   const setupAxios = () =&gt; {\n       axios.defaults.headers.common['X-XSRF-TOKEN'] = \n           document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content');\n\n       \/\/ Cookie\u304b\u3089CSRF\u30c8\u30fc\u30af\u30f3\u3092\u53d6\u5f97\n       axios.get('\/sanctum\/csrf-cookie').then(response =&gt; {\n           console.log('CSRF cookie set');\n       });\n   };\n\n   export default setupAxios;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/components\/LoginForm.jsx\n   import React, { useState } from 'react';\n   import axios from 'axios';\n\n   const LoginForm = () =&gt; {\n       const [credentials, setCredentials] = useState({\n           email: '',\n           password: ''\n       });\n       const [error, setError] = useState('');\n\n       const handleSubmit = async (e) =&gt; {\n           e.preventDefault();\n           try {\n               \/\/ CSRF\u4fdd\u8b77\u3055\u308c\u305f\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306b\u30ea\u30af\u30a8\u30b9\u30c8\n               const response = await axios.post('\/api\/login', credentials);\n               window.location.href = '\/dashboard';\n           } catch (err) {\n               setError('\u30ed\u30b0\u30a4\u30f3\u306b\u5931\u6557\u3057\u307e\u3057\u305f');\n           }\n       };\n\n       return (\n           &lt;form onSubmit={handleSubmit} className=\"space-y-4\"&gt;\n               {\/* \u30d5\u30a9\u30fc\u30e0\u306e\u5185\u5bb9 *\/}\n           &lt;\/form&gt;\n       );\n   };<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ config\/session.php\n   return [\n       'driver' =&gt; env('SESSION_DRIVER', 'redis'),\n       'lifetime' =&gt; env('SESSION_LIFETIME', 120),\n       'expire_on_close' =&gt; false,\n       'encrypt' =&gt; true,\n       'secure' =&gt; env('SESSION_SECURE_COOKIE', true),\n       'same_site' =&gt; 'lax',\n   ];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Middleware\/CustomSessionHandler.php\n   namespace App\\Http\\Middleware;\n\n   use Closure;\n   use Illuminate\\Http\\Request;\n\n   class CustomSessionHandler\n   {\n       public function handle(Request $request, Closure $next)\n       {\n           \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u76e3\u8996\n           if (auth()-&gt;check()) {\n               $user = auth()-&gt;user();\n               $user-&gt;last_activity = now();\n               $user-&gt;save();\n           }\n\n           \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d8\u30c3\u30c0\u30fc\u8a2d\u5b9a\n           $response = $next($request);\n           $response-&gt;headers-&gt;set('X-Frame-Options', 'DENY');\n           $response-&gt;headers-&gt;set('X-Content-Type-Options', 'nosniff');\n           $response-&gt;headers-&gt;set('X-XSS-Protection', '1; mode=block');\n\n           return $response;\n       }\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30c3\u30b7\u30e7\u30f3\u72b6\u614b\u306e\u7ba1\u7406\uff08React\u5074\uff09<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/hooks\/useAuth.js\n   import { create } from 'zustand';\n\n   const useAuth = create((set) =&gt; ({\n       user: null,\n       isAuthenticated: false,\n\n       checkAuth: async () =&gt; {\n           try {\n               const response = await axios.get('\/api\/user');\n               set({\n                   user: response.data,\n                   isAuthenticated: true\n               });\n           } catch (error) {\n               set({\n                   user: null,\n                   isAuthenticated: false\n               });\n           }\n       },\n\n       \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u691c\u77e5\n       setupSessionMonitor: () =&gt; {\n           let inactivityTimer;\n\n           const resetTimer = () =&gt; {\n               clearTimeout(inactivityTimer);\n               inactivityTimer = setTimeout(() =&gt; {\n                   \/\/ \u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u6642\u306e\u51e6\u7406\n                   window.location.href = '\/login';\n               }, 30 * 60 * 1000); \/\/ 30\u5206\n           };\n\n           \/\/ \u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\u306e\u76e3\u8996\n           ['mousedown', 'keydown', 'scroll', 'touchstart'].forEach(event =&gt; {\n               document.addEventListener(event, resetTimer);\n           });\n\n           resetTimer();\n       }\n   }));\n\n   export default useAuth;<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8981\u4ef6\u3092\u6e80\u305f\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5b89\u5168\u306a\u8a8d\u8a3c\u30d7\u30ed\u30bb\u30b9<\/li>\n\n\n\n<li>CSRF\u653b\u6483\u304b\u3089\u306e\u4fdd\u8b77<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30a2\u306a\u30bb\u30c3\u30b7\u30e7\u30f3\u7ba1\u7406<\/li>\n\n\n\n<li>XSS\u653b\u6483\u5bfe\u7b56<\/li>\n\n\n\n<li>\u30bb\u30c3\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u306e\u9069\u5207\u306a\u51e6\u7406<\/li>\n<\/ul>\n\n\n\n<p>\u7279\u306b\u91cd\u8981\u306a\u306e\u306f\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u4e21\u65b9\u3067\u4e00\u8cab\u3057\u305f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3059\u3002\u307e\u305f\u3001\u5b9f\u969b\u306e\u904b\u7528\u74b0\u5883\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u57fa\u672c\u7684\u306a\u5bfe\u7b56\u306b\u52a0\u3048\u3066\u3001\u5b9a\u671f\u7684\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u76e3\u67fb\u3084\u30da\u30cd\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\u30c6\u30b9\u30c8\u3092\u5b9f\u65bd\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u624b\u6cd5<\/h2>\n\n\n\n<p>Laravel\u3068React\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u6700\u5927\u9650\u306b\u5f15\u304d\u51fa\u3059\u305f\u3081\u306e\u6700\u9069\u5316\u624b\u6cd5\u306b\u3064\u3044\u3066\u3001\u5177\u4f53\u7684\u306a\u5b9f\u88c5\u4f8b\u3068\u3068\u3082\u306b\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30d0\u30f3\u30c9\u30eb\u30b5\u30a4\u30ba\u306e\u6700\u9069\u5316\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Webpack\u306e\u6700\u9069\u5316\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ webpack.mix.js\n   const mix = require('laravel-mix');\n   const CompressionPlugin = require('compression-webpack-plugin');\n\n   mix.js('resources\/js\/app.js', 'public\/js')\n      .react()\n      .postCss('resources\/css\/app.css', 'public\/css', [\n          require('tailwindcss'),\n      ])\n      .webpackConfig({\n          optimization: {\n              splitChunks: {\n                  chunks: 'all',\n                  minSize: 20000,\n                  maxSize: 244000,\n                  cacheGroups: {\n                      vendor: {\n                          test: \/[\\\\\/]node_modules[\\\\\/]\/,\n                          name: 'vendor',\n                          chunks: 'all'\n                      }\n                  }\n              }\n          },\n          plugins: [\n              new CompressionPlugin({\n                  filename: '[path][base].gz',\n                  algorithm: 'gzip',\n                  test: \/\\.js$|\\.css$|\\.html$\/,\n                  threshold: 10240,\n                  minRatio: 0.8\n              })\n          ]\n      });<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u9045\u5ef6\u30ed\u30fc\u30c9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/router.js\n   import React, { Suspense, lazy } from 'react';\n   import { BrowserRouter, Routes, Route } from 'react-router-dom';\n   import LoadingSpinner from '.\/components\/LoadingSpinner';\n\n   \/\/ \u9045\u5ef6\u30ed\u30fc\u30c9\u3059\u308b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\n   const Dashboard = lazy(() =&gt; import('.\/pages\/Dashboard'));\n   const UserProfile = lazy(() =&gt; import('.\/pages\/UserProfile'));\n   const Reports = lazy(() =&gt; import('.\/pages\/Reports'));\n\n   const Router = () =&gt; {\n       return (\n           &lt;BrowserRouter&gt;\n               &lt;Suspense fallback={&lt;LoadingSpinner \/&gt;}&gt;\n                   &lt;Routes&gt;\n                       &lt;Route path=\"\/dashboard\" element={&lt;Dashboard \/&gt;} \/&gt;\n                       &lt;Route path=\"\/profile\" element={&lt;UserProfile \/&gt;} \/&gt;\n                       &lt;Route path=\"\/reports\" element={&lt;Reports \/&gt;} \/&gt;\n                   &lt;\/Routes&gt;\n               &lt;\/Suspense&gt;\n           &lt;\/BrowserRouter&gt;\n       );\n   };<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u52b9\u7387\u7684\u306aAPI\u901a\u4fe1\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u3068\u518d\u5229\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/hooks\/useDataFetching.js\n   import { useQuery, useQueryClient } from 'react-query';\n   import axios from 'axios';\n\n   export const useDataFetching = (endpoint) =&gt; {\n       const queryClient = useQueryClient();\n\n       const { data, isLoading, error } = useQuery(\n           endpoint,\n           async () =&gt; {\n               const response = await axios.get(`\/api\/${endpoint}`);\n               return response.data;\n           },\n           {\n               staleTime: 5 * 60 * 1000, \/\/ 5\u5206\u9593\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u6709\u52b9\u306b\n               cacheTime: 30 * 60 * 1000, \/\/ 30\u5206\u9593\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u4fdd\u6301\n               onError: (error) =&gt; {\n                   console.error('\u30c7\u30fc\u30bf\u53d6\u5f97\u30a8\u30e9\u30fc:', error);\n               }\n           }\n       );\n\n       \/\/ \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u4e8b\u524d\u306b\u66f4\u65b0\n       const prefetchData = async () =&gt; {\n           await queryClient.prefetchQuery(endpoint, async () =&gt; {\n               const response = await axios.get(`\/api\/${endpoint}`);\n               return response.data;\n           });\n       };\n\n       return { data, isLoading, error, prefetchData };\n   };<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d0\u30c3\u30c1\u51e6\u7406\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Controllers\/BatchController.php\n   namespace App\\Http\\Controllers;\n\n   use Illuminate\\Http\\Request;\n   use Illuminate\\Support\\Facades\\DB;\n\n   class BatchController extends Controller\n   {\n       public function batchProcess(Request $request)\n       {\n           \/\/ \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u30d0\u30c3\u30c1\u51e6\u7406\u3092\u6700\u9069\u5316\n           return DB::transaction(function () use ($request) {\n               $chunks = collect($request-&gt;data)-&gt;chunk(1000);\n\n               foreach ($chunks as $chunk) {\n                   \/\/ \u30d0\u30eb\u30af\u30a4\u30f3\u30b5\u30fc\u30c8\u306e\u5b9f\u884c\n                   DB::table('target_table')-&gt;insert($chunk-&gt;toArray());\n               }\n\n               \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u66f4\u65b0\n               Cache::tags(['data'])-&gt;flush();\n\n               return response()-&gt;json(['message' =&gt; '\u30d0\u30c3\u30c1\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f']);\n           });\n       }\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u8996\u70b9\u3068\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u968e\u5c64\u7684\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Services\/CacheService.php\n   namespace App\\Services;\n\n   use Illuminate\\Support\\Facades\\Cache;\n   use Illuminate\\Support\\Facades\\Redis;\n\n   class CacheService\n   {\n       public function getOrSetCache($key, $callback, $ttl = 3600)\n       {\n           \/\/ \u307e\u305aRedis\u3092\u30c1\u30a7\u30c3\u30af\n           $redisData = Redis::get($key);\n           if ($redisData) {\n               return json_decode($redisData);\n           }\n\n           \/\/ \u6b21\u306bLaravel\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u30c1\u30a7\u30c3\u30af\n           $cachedData = Cache::get($key);\n           if ($cachedData) {\n               \/\/ Redis\u306b\u3082\u30c7\u30fc\u30bf\u3092\u4fdd\u5b58\n               Redis::setex($key, $ttl, json_encode($cachedData));\n               return $cachedData;\n           }\n\n           \/\/ \u30c7\u30fc\u30bf\u304c\u306a\u3044\u5834\u5408\u306f\u751f\u6210\n           $freshData = $callback();\n\n           \/\/ \u4e21\u65b9\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u4fdd\u5b58\n           Cache::put($key, $freshData, $ttl);\n           Redis::setex($key, $ttl, json_encode($freshData));\n\n           return $freshData;\n       }\n\n       public function invalidateCache($key)\n       {\n           Cache::forget($key);\n           Redis::del($key);\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/utils\/serviceWorker.js\n   \/\/ Service Worker\u306e\u767b\u9332\n   if ('serviceWorker' in navigator) {\n       window.addEventListener('load', () =&gt; {\n           navigator.serviceWorker.register('\/service-worker.js')\n               .then(registration =&gt; {\n                   console.log('ServiceWorker registered');\n               })\n               .catch(error =&gt; {\n                   console.error('ServiceWorker registration failed:', error);\n               });\n       });\n   }\n\n   \/\/ service-worker.js\n   const CACHE_NAME = 'v1';\n   const urlsToCache = [\n       '\/',\n       '\/css\/app.css',\n       '\/js\/app.js',\n       '\/images\/logo.png'\n   ];\n\n   self.addEventListener('install', event =&gt; {\n       event.waitUntil(\n           caches.open(CACHE_NAME)\n               .then(cache =&gt; cache.addAll(urlsToCache))\n       );\n   });\n\n   self.addEventListener('fetch', event =&gt; {\n       event.respondWith(\n           caches.match(event.request)\n               .then(response =&gt; {\n                   if (response) {\n                       return response;\n                   }\n                   return fetch(event.request);\n               })\n       );\n   });<\/pre>\n\n\n\n<p>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d0\u30f3\u30c9\u30eb\u30b5\u30a4\u30ba\u306e\u6700\u5c0f\u5316<\/li>\n\n\n\n<li>\u52b9\u7387\u7684\u306a\u30b3\u30fc\u30c9\u5206\u5272<\/li>\n\n\n\n<li>API\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u6700\u9069\u5316<\/li>\n\n\n\n<li>\u9069\u5207\u306a\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565<\/li>\n\n\n\n<li>Service Worker\u306e\u6d3b\u7528<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u6700\u9069\u5316\u3092\u9069\u5207\u306b\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5fdc\u7b54\u6027\u3068\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u3092\u5927\u5e45\u306b\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u305f\u3060\u3057\u3001\u6700\u9069\u5316\u306f\u7d99\u7d9a\u7684\u306a\u30d7\u30ed\u30bb\u30b9\u3067\u3042\u308a\u3001\u5b9a\u671f\u7684\u306a\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u8a08\u6e2c\u3068\u6539\u5584\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-16\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u89e3\u6c7a\u7b56<\/h2>\n\n\n\n<p>Laravel\u3068React\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u958b\u767a\u3067\u3088\u304f\u906d\u9047\u3059\u308b\u5177\u4f53\u7684\u306a\u8ab2\u984c\u3068\u3001\u305d\u306e\u89e3\u6c7a\u65b9\u6cd5\u306b\u3064\u3044\u3066\u5b9f\u88c5\u4f8b\u3068\u3068\u3082\u306b\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6a5f\u80fd\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Controllers\/FileUploadController.php\n   namespace App\\Http\\Controllers;\n\n   use Illuminate\\Http\\Request;\n   use Illuminate\\Support\\Facades\\Storage;\n   use App\\Jobs\\ProcessUploadedFile;\n\n   class FileUploadController extends Controller\n   {\n       public function upload(Request $request)\n       {\n           $request-&gt;validate([\n               'file' =&gt; 'required|file|max:10240|mimes:pdf,doc,docx,jpg,png',\n           ]);\n\n           try {\n               $file = $request-&gt;file('file');\n               $path = $file-&gt;store('uploads', 'public');\n\n               \/\/ \u975e\u540c\u671f\u51e6\u7406\u3067\u753b\u50cf\u306e\u6700\u9069\u5316\u3084\u30a6\u30a4\u30eb\u30b9\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u884c\n               ProcessUploadedFile::dispatch($path);\n\n               return response()-&gt;json([\n                   'message' =&gt; '\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u6210\u529f\u3057\u307e\u3057\u305f',\n                   'path' =&gt; Storage::url($path)\n               ]);\n           } catch (\\Exception $e) {\n               return response()-&gt;json([\n                   'message' =&gt; '\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f',\n                   'error' =&gt; $e-&gt;getMessage()\n               ], 500);\n           }\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/components\/FileUploader.jsx\n   import React, { useState, useCallback } from 'react';\n   import { useDropzone } from 'react-dropzone';\n\n   const FileUploader = () =&gt; {\n       const [uploadProgress, setUploadProgress] = useState(0);\n       const [uploadedFiles, setUploadedFiles] = useState([]);\n\n       const onDrop = useCallback(async (acceptedFiles) =&gt; {\n           const formData = new FormData();\n           formData.append('file', acceptedFiles[0]);\n\n           try {\n               const response = await axios.post('\/api\/upload', formData, {\n                   headers: {\n                       'Content-Type': 'multipart\/form-data'\n                   },\n                   onUploadProgress: (progressEvent) =&gt; {\n                       const progress = Math.round(\n                           (progressEvent.loaded * 100) \/ progressEvent.total\n                       );\n                       setUploadProgress(progress);\n                   }\n               });\n\n               setUploadedFiles(prev =&gt; [...prev, response.data]);\n           } catch (error) {\n               console.error('\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u30a8\u30e9\u30fc:', error);\n           }\n       }, []);\n\n       const { getRootProps, getInputProps, isDragActive } = useDropzone({\n           onDrop,\n           accept: {\n               'image\/*': ['.jpeg', '.jpg', '.png'],\n               'application\/pdf': ['.pdf'],\n               'application\/msword': ['.doc', '.docx']\n           },\n           maxSize: 10485760 \/\/ 10MB\n       });\n\n       return (\n           &lt;div className=\"max-w-2xl mx-auto\"&gt;\n               &lt;div\n                   {...getRootProps()}\n                   className={`border-2 border-dashed p-8 text-center \n                       ${isDragActive ? 'border-blue-500 bg-blue-50' : 'border-gray-300'}`}\n               &gt;\n                   &lt;input {...getInputProps()} \/&gt;\n                   {isDragActive ? (\n                       &lt;p&gt;\u30d5\u30a1\u30a4\u30eb\u3092\u30c9\u30ed\u30c3\u30d7\u3057\u3066\u304f\u3060\u3055\u3044&lt;\/p&gt;\n                   ) : (\n                       &lt;p&gt;\u30d5\u30a1\u30a4\u30eb\u3092\u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7\u3001\u307e\u305f\u306f\u30af\u30ea\u30c3\u30af\u3057\u3066\u9078\u629e&lt;\/p&gt;\n                   )}\n               &lt;\/div&gt;\n\n               {uploadProgress &gt; 0 &amp;&amp; uploadProgress &lt; 100 &amp;&amp; (\n                   &lt;div className=\"mt-4\"&gt;\n                       &lt;div className=\"w-full bg-gray-200 rounded\"&gt;\n                           &lt;div\n                               className=\"bg-blue-600 rounded h-2\"\n                               style={{ width: `${uploadProgress}%` }}\n                           \/&gt;\n                       &lt;\/div&gt;\n                   &lt;\/div&gt;\n               )}\n\n               {uploadedFiles.length &gt; 0 &amp;&amp; (\n                   &lt;div className=\"mt-4\"&gt;\n                       &lt;h3 className=\"text-lg font-semibold\"&gt;\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6e08\u307f\u30d5\u30a1\u30a4\u30eb&lt;\/h3&gt;\n                       &lt;ul className=\"mt-2\"&gt;\n                           {uploadedFiles.map((file, index) =&gt; (\n                               &lt;li key={index} className=\"text-sm text-gray-600\"&gt;\n                                   {file.path}\n                               &lt;\/li&gt;\n                           ))}\n                       &lt;\/ul&gt;\n                   &lt;\/div&gt;\n               )}\n           &lt;\/div&gt;\n       );\n   };\n\n   export default FileUploader;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u901a\u4fe1\u306e\u5b9f\u73fe\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>WebSocket\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ config\/broadcasting.php\n   'pusher' =&gt; [\n       'driver' =&gt; 'pusher',\n       'key' =&gt; env('PUSHER_APP_KEY'),\n       'secret' =&gt; env('PUSHER_APP_SECRET'),\n       'app_id' =&gt; env('PUSHER_APP_ID'),\n       'options' =&gt; [\n           'cluster' =&gt; env('PUSHER_APP_CLUSTER'),\n           'encrypted' =&gt; true,\n       ],\n   ],<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30a4\u30d9\u30f3\u30c8\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Events\/MessageSent.php\n   namespace App\\Events;\n\n   use Illuminate\\Broadcasting\\Channel;\n   use Illuminate\\Broadcasting\\InteractsWithSockets;\n   use Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\n   use Illuminate\\Foundation\\Events\\Dispatchable;\n\n   class MessageSent implements ShouldBroadcast\n   {\n       use Dispatchable, InteractsWithSockets;\n\n       public $message;\n\n       public function __construct($message)\n       {\n           $this-&gt;message = $message;\n       }\n\n       public function broadcastOn()\n       {\n           return new Channel('chat');\n       }\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>React\u3067\u306e\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u51e6\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/components\/Chat.jsx\n   import React, { useState, useEffect } from 'react';\n   import Echo from 'laravel-echo';\n\n   const Chat = () =&gt; {\n       const [messages, setMessages] = useState([]);\n       const [newMessage, setNewMessage] = useState('');\n\n       useEffect(() =&gt; {\n           const echo = new Echo({\n               broadcaster: 'pusher',\n               key: process.env.MIX_PUSHER_APP_KEY,\n               cluster: process.env.MIX_PUSHER_APP_CLUSTER,\n               encrypted: true\n           });\n\n           echo.channel('chat')\n               .listen('MessageSent', (e) =&gt; {\n                   setMessages(prev =&gt; [...prev, e.message]);\n               });\n\n           return () =&gt; {\n               echo.leave('chat');\n           };\n       }, []);\n\n       const sendMessage = async () =&gt; {\n           try {\n               await axios.post('\/api\/messages', { content: newMessage });\n               setNewMessage('');\n           } catch (error) {\n               console.error('\u30e1\u30c3\u30bb\u30fc\u30b8\u9001\u4fe1\u30a8\u30e9\u30fc:', error);\n           }\n       };\n\n       return (\n           &lt;div className=\"max-w-2xl mx-auto\"&gt;\n               &lt;div className=\"border rounded-lg p-4\"&gt;\n                   &lt;div className=\"h-96 overflow-y-auto\"&gt;\n                       {messages.map((message, index) =&gt; (\n                           &lt;div key={index} className=\"mb-2\"&gt;\n                               &lt;p&gt;{message.content}&lt;\/p&gt;\n                           &lt;\/div&gt;\n                       ))}\n                   &lt;\/div&gt;\n                   &lt;div className=\"mt-4 flex\"&gt;\n                       &lt;input\n                           type=\"text\"\n                           value={newMessage}\n                           onChange={(e) =&gt; setNewMessage(e.target.value)}\n                           className=\"flex-1 border rounded-l px-4 py-2\"\n                           placeholder=\"\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5165\u529b...\"\n                       \/&gt;\n                       &lt;button\n                           onClick={sendMessage}\n                           className=\"bg-blue-500 text-white px-6 py-2 rounded-r\"\n                       &gt;\n                           \u9001\u4fe1\n                       &lt;\/button&gt;\n                   &lt;\/div&gt;\n               &lt;\/div&gt;\n           &lt;\/div&gt;\n       );\n   };\n\n   export default Chat;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u8907\u96d1\u306a\u30d5\u30a9\u30fc\u30e0\u51e6\u7406\u306e\u5b9f\u88c5\u624b\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30a9\u30fc\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Http\/Requests\/ComplexFormRequest.php\n   namespace App\\Http\\Requests;\n\n   use Illuminate\\Foundation\\Http\\FormRequest;\n\n   class ComplexFormRequest extends FormRequest\n   {\n       public function rules()\n       {\n           return [\n               'title' =&gt; 'required|max:255',\n               'items' =&gt; 'required|array|min:1',\n               'items.*.name' =&gt; 'required|string',\n               'items.*.quantity' =&gt; 'required|integer|min:1',\n               'attachments' =&gt; 'array',\n               'attachments.*' =&gt; 'file|mimes:pdf,doc,docx|max:2048'\n           ];\n       }\n\n       public function messages()\n       {\n           return [\n               'items.*.name.required' =&gt; '\u9805\u76ee\u540d\u306f\u5fc5\u9808\u3067\u3059',\n               'items.*.quantity.min' =&gt; '\u6570\u91cf\u306f1\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059'\n           ];\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u52d5\u7684\u30d5\u30a9\u30fc\u30e0\u306eReact\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/components\/ComplexForm.jsx\n   import React, { useState } from 'react';\n   import { useForm, useFieldArray } from 'react-hook-form';\n\n   const ComplexForm = () =&gt; {\n       const { register, control, handleSubmit, formState: { errors } } = useForm({\n           defaultValues: {\n               title: '',\n               items: [{ name: '', quantity: 1 }]\n           }\n       });\n\n       const { fields, append, remove } = useFieldArray({\n           control,\n           name: 'items'\n       });\n\n       const onSubmit = async (data) =&gt; {\n           try {\n               const formData = new FormData();\n               formData.append('title', data.title);\n\n               data.items.forEach((item, index) =&gt; {\n                   formData.append(`items[${index}][name]`, item.name);\n                   formData.append(`items[${index}][quantity]`, item.quantity);\n               });\n\n               const response = await axios.post('\/api\/complex-form', formData);\n               console.log('\u9001\u4fe1\u6210\u529f:', response.data);\n           } catch (error) {\n               console.error('\u9001\u4fe1\u30a8\u30e9\u30fc:', error);\n           }\n       };\n\n       return (\n           &lt;form onSubmit={handleSubmit(onSubmit)} className=\"max-w-2xl mx-auto\"&gt;\n               &lt;div className=\"mb-4\"&gt;\n                   &lt;label className=\"block text-sm font-medium mb-2\"&gt;\n                       \u30bf\u30a4\u30c8\u30eb\n                   &lt;\/label&gt;\n                   &lt;input\n                       {...register('title', { required: '\u5fc5\u9808\u9805\u76ee\u3067\u3059' })}\n                       className=\"w-full border rounded px-3 py-2\"\n                   \/&gt;\n                   {errors.title &amp;&amp; (\n                       &lt;p className=\"text-red-500 text-sm mt-1\"&gt;\n                           {errors.title.message}\n                       &lt;\/p&gt;\n                   )}\n               &lt;\/div&gt;\n\n               &lt;div className=\"mb-4\"&gt;\n                   &lt;label className=\"block text-sm font-medium mb-2\"&gt;\n                       \u9805\u76ee\u4e00\u89a7\n                   &lt;\/label&gt;\n                   {fields.map((field, index) =&gt; (\n                       &lt;div key={field.id} className=\"flex gap-4 mb-2\"&gt;\n                           &lt;input\n                               {...register(`items.${index}.name`)}\n                               placeholder=\"\u9805\u76ee\u540d\"\n                               className=\"flex-1 border rounded px-3 py-2\"\n                           \/&gt;\n                           &lt;input\n                               type=\"number\"\n                               {...register(`items.${index}.quantity`)}\n                               className=\"w-24 border rounded px-3 py-2\"\n                           \/&gt;\n                           &lt;button\n                               type=\"button\"\n                               onClick={() =&gt; remove(index)}\n                               className=\"px-3 py-2 bg-red-500 text-white rounded\"\n                           &gt;\n                               \u524a\u9664\n                           &lt;\/button&gt;\n                       &lt;\/div&gt;\n                   ))}\n                   &lt;button\n                       type=\"button\"\n                       onClick={() =&gt; append({ name: '', quantity: 1 })}\n                       className=\"mt-2 px-4 py-2 bg-green-500 text-white rounded\"\n                   &gt;\n                       \u9805\u76ee\u3092\u8ffd\u52a0\n                   &lt;\/button&gt;\n               &lt;\/div&gt;\n\n               &lt;button\n                   type=\"submit\"\n                   className=\"w-full bg-blue-500 text-white py-2 rounded\"\n               &gt;\n                   \u9001\u4fe1\n               &lt;\/button&gt;\n           &lt;\/form&gt;\n       );\n   };\n\n   export default ComplexForm;<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u4f8b\u306f\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u3088\u304f\u76f4\u9762\u3059\u308b\u8ab2\u984c\u306b\u5bfe\u3059\u308b\u5177\u4f53\u7684\u306a\u89e3\u6c7a\u7b56\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002\u5404\u5b9f\u88c5\u306b\u304a\u3044\u3066\u4ee5\u4e0b\u306e\u30dd\u30a4\u30f3\u30c8\u306b\u6ce8\u610f\u3092\u6255\u3063\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/li>\n\n\n\n<li>\u30e6\u30fc\u30b6\u30fc\u30a8\u30af\u30b9\u30da\u30ea\u30a8\u30f3\u30b9<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u3092\u57fa\u306b\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8981\u4ef6\u306b\u5408\u308f\u305b\u3066\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u306a\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u3068CI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3<\/h2>\n\n\n\n<p>Laravel\u3068React\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u672c\u756a\u74b0\u5883\u3078\u306e\u5c55\u958b\u3068\u3001\u7d99\u7d9a\u7684\u30a4\u30f3\u30c6\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\/\u30c7\u30ea\u30d0\u30ea\u30fc\u306e\u5b9f\u88c5\u65b9\u6cd5\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u672c\u756a\u74b0\u5883\u306e\u69cb\u7bc9\u624b\u9806<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b5\u30fc\u30d0\u30fc\u74b0\u5883\u306e\u6e96\u5099<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   # \u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   sudo apt update\n   sudo apt install nginx php8.1-fpm php8.1-mbstring php8.1-xml php8.1-mysql \\\n       php8.1-curl php8.1-zip composer nodejs npm redis-server\n\n   # Nginx\u306e\u8a2d\u5b9a\n   sudo nano \/etc\/nginx\/sites-available\/laravel-react<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   # \/etc\/nginx\/sites-available\/laravel-react\n   server {\n       listen 80;\n       server_name your-domain.com;\n       root \/var\/www\/laravel-react\/public;\n\n       add_header X-Frame-Options \"SAMEORIGIN\";\n       add_header X-Content-Type-Options \"nosniff\";\n\n       index index.php;\n\n       charset utf-8;\n\n       location \/ {\n           try_files $uri $uri\/ \/index.php?$query_string;\n       }\n\n       location = \/favicon.ico { access_log off; log_not_found off; }\n       location = \/robots.txt  { access_log off; log_not_found off; }\n\n       error_page 404 \/index.php;\n\n       location ~ \\.php$ {\n           fastcgi_pass unix:\/var\/run\/php\/php8.1-fpm.sock;\n           fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;\n           include fastcgi_params;\n       }\n\n       location ~ \/\\.(?!well-known).* {\n           deny all;\n       }\n\n       # \u9759\u7684\u30a2\u30bb\u30c3\u30c8\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u8a2d\u5b9a\n       location ~* \\.(js|css|png|jpg|jpeg|gif|ico)$ {\n           expires max;\n           log_not_found off;\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u30b9\u30af\u30ea\u30d7\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   #!\/bin\/bash\n   # deploy.sh\n\n   # \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u79fb\u52d5\n   cd \/var\/www\/laravel-react\n\n   # \u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u30e2\u30fc\u30c9\u3092\u6709\u52b9\u5316\n   php artisan down\n\n   # \u6700\u65b0\u306e\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\n   git pull origin main\n\n   # Composer\u306e\u4f9d\u5b58\u95a2\u4fc2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   composer install --no-interaction --prefer-dist --optimize-autoloader\n\n   # \u74b0\u5883\u8a2d\u5b9a\n   php artisan config:cache\n   php artisan route:cache\n   php artisan view:cache\n\n   # \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\n   php artisan migrate --force\n\n   # \u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u30d3\u30eb\u30c9\n   npm ci\n   npm run build\n\n   # \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2\n   php artisan cache:clear\n\n   # \u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u30e2\u30fc\u30c9\u3092\u89e3\u9664\n   php artisan up\n\n   # Nginx\u306e\u8a2d\u5b9a\u3092\u30ea\u30ed\u30fc\u30c9\n   sudo systemctl reload nginx<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u81ea\u52d5\u30c6\u30b9\u30c8\u306e\u5c0e\u5165\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>PHPUnit\u30c6\u30b9\u30c8\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ tests\/Feature\/ApiTest.php\n   namespace Tests\\Feature;\n\n   use Tests\\TestCase;\n   use App\\Models\\User;\n   use Illuminate\\Foundation\\Testing\\RefreshDatabase;\n\n   class ApiTest extends TestCase\n   {\n       use RefreshDatabase;\n\n       public function test_api_authentication()\n       {\n           $user = User::factory()-&gt;create();\n\n           $response = $this-&gt;postJson('\/api\/login', [\n               'email' =&gt; $user-&gt;email,\n               'password' =&gt; 'password'\n           ]);\n\n           $response-&gt;assertStatus(200)\n                   -&gt;assertJsonStructure(['token']);\n       }\n\n       public function test_protected_route_access()\n       {\n           $user = User::factory()-&gt;create();\n           $token = $user-&gt;createToken('test-token')-&gt;plainTextToken;\n\n           $response = $this-&gt;withHeaders([\n               'Authorization' =&gt; 'Bearer ' . $token,\n           ])-&gt;getJson('\/api\/user-data');\n\n           $response-&gt;assertStatus(200);\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u30c6\u30b9\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ resources\/js\/components\/__tests__\/Form.test.js\n   import { render, screen, fireEvent } from '@testing-library\/react';\n   import userEvent from '@testing-library\/user-event';\n   import Form from '..\/Form';\n\n   describe('Form Component', () =&gt; {\n       it('validates required fields', async () =&gt; {\n           render(&lt;Form \/&gt;);\n\n           const submitButton = screen.getByRole('button', { name: \/submit\/i });\n           await userEvent.click(submitButton);\n\n           expect(screen.getByText(\/\u540d\u524d\u306f\u5fc5\u9808\u3067\u3059\/i)).toBeInTheDocument();\n       });\n\n       it('submits form with valid data', async () =&gt; {\n           const mockSubmit = jest.fn();\n           render(&lt;Form onSubmit={mockSubmit} \/&gt;);\n\n           await userEvent.type(\n               screen.getByLabelText(\/\u540d\u524d\/i),\n               '\u30c6\u30b9\u30c8\u30e6\u30fc\u30b6\u30fc'\n           );\n\n           const submitButton = screen.getByRole('button', { name: \/submit\/i });\n           await userEvent.click(submitButton);\n\n           expect(mockSubmit).toHaveBeenCalledWith({\n               name: '\u30c6\u30b9\u30c8\u30e6\u30fc\u30b6\u30fc'\n           });\n       });\n   });<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u7d99\u7d9a\u7684\u306a\u30c7\u30d7\u30ed\u30a4\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>GitHub Actions\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   # .github\/workflows\/deploy.yml\n   name: Deploy Laravel React App\n\n   on:\n     push:\n       branches: [ main ]\n\n   jobs:\n     deploy:\n       runs-on: ubuntu-latest\n\n       steps:\n       - uses: actions\/checkout@v3\n\n       - name: Setup PHP\n         uses: shivammathur\/setup-php@v2\n         with:\n           php-version: '8.1'\n\n       - name: Setup Node.js\n         uses: actions\/setup-node@v3\n         with:\n           node-version: '16'\n\n       - name: Install PHP Dependencies\n         run: composer install --prefer-dist --no-interaction --no-dev\n\n       - name: Install Node Dependencies\n         run: npm ci\n\n       - name: Build Frontend Assets\n         run: npm run build\n\n       - name: Run Tests\n         run: |\n           cp .env.example .env\n           php artisan key:generate\n           php artisan test\n           npm test\n\n       - name: Deploy to Production\n         if: success()\n         uses: appleboy\/ssh-action@master\n         with:\n           host: ${{ secrets.SSH_HOST }}\n           username: ${{ secrets.SSH_USERNAME }}\n           key: ${{ secrets.SSH_PRIVATE_KEY }}\n           script: |\n             cd \/var\/www\/laravel-react\n             git pull origin main\n             composer install --no-interaction --prefer-dist --optimize-autoloader\n             php artisan config:cache\n             php artisan route:cache\n             php artisan view:cache\n             npm ci\n             npm run build\n             php artisan migrate --force\n             php artisan cache:clear\n             sudo systemctl reload nginx<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u76e3\u8996\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ app\/Providers\/AppServiceProvider.php\n   public function boot()\n   {\n       \/\/ \u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u5f8c\u306e\u76e3\u8996\u8a2d\u5b9a\n       if ($this-&gt;app-&gt;environment('production')) {\n           URL::forceScheme('https');\n\n           \/\/ Sentry\u306e\u8a2d\u5b9a\uff08\u30a8\u30e9\u30fc\u76e3\u8996\uff09\n           \\Sentry\\init([\n               'dsn' =&gt; env('SENTRY_DSN'),\n               'environment' =&gt; env('APP_ENV'),\n           ]);\n\n           \/\/ \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u76e3\u8996\n           \\DB::listen(function ($query) {\n               if ($query-&gt;time &gt; 100) {  \/\/ 100ms\u4ee5\u4e0a\u306e\u30af\u30a8\u30ea\u3092\u30ed\u30b0\n                   \\Log::warning('Long running query detected', [\n                       'sql' =&gt; $query-&gt;sql,\n                       'time' =&gt; $query-&gt;time\n                   ]);\n               }\n           });\n       }\n   }<\/pre>\n\n\n\n<p>\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u3068CI\/CD\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306e\u91cd\u8981\u306a\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u74b0\u5883\u8a2d\u5b9a\u306e\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u672c\u756a\u74b0\u5883\u7528\u306e<code>.env<\/code>\u30d5\u30a1\u30a4\u30eb\u306e\u9069\u5207\u306a\u7ba1\u7406<\/li>\n\n\n\n<li>\u74b0\u5883\u5909\u6570\u306e\u6697\u53f7\u5316\u3068\u5b89\u5168\u306a\u53d7\u3051\u6e21\u3057<\/li>\n\n\n\n<li>\u5404\u74b0\u5883\uff08\u958b\u767a\/\u30b9\u30c6\u30fc\u30b8\u30f3\u30b0\/\u672c\u756a\uff09\u306e\u8a2d\u5b9a\u5206\u96e2<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SSL\u306e\u8a2d\u5b9a\u3068\u5f37\u5236<\/li>\n\n\n\n<li>\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u306e\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d8\u30c3\u30c0\u30fc\u306e\u8ffd\u52a0<\/li>\n\n\n\n<li>\u5b9a\u671f\u7684\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a2\u30bb\u30c3\u30c8\u306e\u6700\u9069\u5316\u3068\u30ad\u30e3\u30c3\u30b7\u30e5\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u6700\u9069\u5316<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>CDN\u306e\u6d3b\u7528<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u76e3\u8996\u3068\u30ed\u30b0\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a8\u30e9\u30fc\u76e3\u8996\u306e\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/li>\n\n\n\n<li>\u30ed\u30b0\u306e\u96c6\u4e2d\u7ba1\u7406<\/li>\n\n\n\n<li>\u30a2\u30e9\u30fc\u30c8\u306e\u8a2d\u5b9a<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u5b89\u5b9a\u3057\u305f\u672c\u756a\u74b0\u5883\u306e\u904b\u7528\u3068\u7d99\u7d9a\u7684\u306a\u6539\u5584\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u307e\u305f\u3001\u81ea\u52d5\u5316\u3055\u308c\u305f\u30c6\u30b9\u30c8\u3068\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u30d7\u30ed\u30bb\u30b9\u306b\u3088\u308a\u3001\u958b\u767a\u30c1\u30fc\u30e0\u306f\u65b0\u6a5f\u80fd\u306e\u958b\u767a\u306b\u96c6\u4e2d\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,12],"tags":[],"class_list":{"0":"post-2713","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-php-laravel","7":"category-php","8":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2713"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2713\/revisions"}],"predecessor-version":[{"id":2715,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2713\/revisions\/2715"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}