{"id":2617,"date":"2025-03-24T08:46:55","date_gmt":"2025-03-23T23:46:55","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2617"},"modified":"2025-03-24T08:47:24","modified_gmt":"2025-03-23T23:47:24","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91laravel-inertia%e3%81%a7%e4%bd%9c%e3%82%8bspa%e5%85%a5%e9%96%80-%e7%92%b0%e5%a2%83%e6%a7%8b%e7%af%89%e3%81%8b%e3%82%89%e5%ae%9f%e8%b7%b5%e6%b4%bb","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2617","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Laravel Inertia\u3067\u4f5c\u308bSPA\u5165\u9580 &#8211; \u74b0\u5883\u69cb\u7bc9\u304b\u3089\u5b9f\u8df5\u6d3b\u7528\u307e\u3067\u5b8c\u5168\u30ac\u30a4\u30c9"},"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 Inertia \u3068\u306f\uff1f SPA \u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u65b0\u6a19\u6e96<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">\u5f93\u6765\u306e SPA \u958b\u767a\u306b\u304a\u3051\u308b\u8ab2\u984c\u3068\u89e3\u6c7a\u7b56<\/a>      <\/li>      <li>        <a href=\"#i-2\">Inertia.js \u304c\u9769\u65b0\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63d0\u4f9b\u3059\u308b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-3\">Laravel\u00d7Inertia \u306e\u7d44\u307f\u5408\u308f\u305b\u304c\u3082\u305f\u3089\u3059\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u59cb\u3081\u308bLaravel Inertia<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">\u5fc5\u8981\u306a\u958b\u767a\u74b0\u5883\u3068\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u78ba\u8a8d<\/a>      <\/li>      <li>        <a href=\"#i-6\">Laravel Breeze\u306b\u3088\u308bInertia\u5c0e\u5165\u624b\u9806<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-7\">Vue.js\/React\u5bfe\u5fdc\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-8\">Inertia\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u30de\u30b9\u30bf\u30fc<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-9\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3068\u30d3\u30e5\u30fc\u306e\u9023\u643a\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-10\">\u30d7\u30ed\u30c3\u30d7\u30b9\u3092\u6d3b\u7528\u3057\u305f\u30c7\u30fc\u30bf\u53d7\u3051\u6e21\u3057<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">\u30da\u30fc\u30b8\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u4f5c\u6210\u3068\u7ba1\u7406<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">\u5b9f\u8df5\u7684\u306aInertia\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u30d5\u30a9\u30fc\u30e0\u51e6\u7406\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-14\">SPA\u3089\u3057\u3044\u753b\u9762\u9077\u79fb\u306e\u5b9f\u73fe\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-15\">\u8a8d\u8a3c\u6a5f\u80fd\u306e\u7d71\u5408\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-16\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u3068\u30c7\u30d0\u30c3\u30b0<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-17\">\u30a2\u30bb\u30c3\u30c8\u306e\u30d0\u30f3\u30c9\u30eb\u8a2d\u5b9a\u3068\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565<\/a>      <\/li>      <li>        <a href=\"#i-18\">Lazy Loading\u306e\u3088\u3046\u306a\u52b9\u679c\u5b9f\u73fe\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-19\">\u958b\u767a\u6642\u306e\u30c7\u30d0\u30c3\u30b0\u30c6\u30af\u30cb\u30c3\u30af\u3068\u30c4\u30fc\u30eb\u6d3b\u7528<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-20\">\u672c\u756a\u74b0\u5883\u3078\u306e\u5c55\u958b\u3068\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-21\">\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>      <\/li>      <li>        <a href=\"#i-22\">\u7d99\u7d9a\u7684\u306a\u7d71\u5408\/\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u69cb\u7bc9<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-23\">\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u6642\u306e\u6ce8\u610f\u70b9\u3068\u4e92\u63db\u6027\u7dad\u6301<\/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 Inertia \u3068\u306f\uff1f SPA \u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u65b0\u6a19\u6e96<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">\u5f93\u6765\u306e SPA \u958b\u767a\u306b\u304a\u3051\u308b\u8ab2\u984c\u3068\u89e3\u6c7a\u7b56<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5f93\u6765\u306eSPA\uff08Single Page Application\uff09\u958b\u767a\u3067\u306f\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092\u5b8c\u5168\u306b\u5206\u96e2\u3059\u308b\u65b9\u5f0f\u304c\u4e3b\u6d41\u3067\u3057\u305f\u3002\u3053\u306e\u65b9\u5f0f\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u8ab2\u984c\u304c\u3042\u308a\u307e\u3057\u305f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u306e\u8907\u96d1\u6027<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3067\u5225\u3005\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u7ba1\u7406\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>API\u306e\u8a2d\u8a08\u30fb\u5b9f\u88c5\u30fb\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u4f5c\u6210\u306b\u591a\u5927\u306a\u6642\u9593\u304c\u5fc5\u8981<\/li>\n\n\n\n<li>\u8a8d\u8a3c\u3084\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u4e8c\u91cd\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3078\u306e\u5f71\u97ff<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u521d\u671f\u30ed\u30fc\u30c9\u6642\u306eJavaScript\u30d0\u30f3\u30c9\u30eb\u30b5\u30a4\u30ba\u304c\u5927\u304d\u304f\u306a\u308a\u304c\u3061<\/li>\n\n\n\n<li>API\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u30aa\u30fc\u30d0\u30fc\u30d8\u30c3\u30c9<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u8907\u96d1\u5316<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>SEO\u5bfe\u7b56\u306e\u56f0\u96e3\u3055<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b5\u30a4\u30c9\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u306b\u3088\u308b\u691c\u7d22\u30a8\u30f3\u30b8\u30f3\u5bfe\u5fdc\u306e\u8ab2\u984c<\/li>\n\n\n\n<li>\u30e1\u30bf\u60c5\u5831\u306e\u52d5\u7684\u66f4\u65b0\u306e\u8907\u96d1\u3055<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">Inertia.js \u304c\u9769\u65b0\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63d0\u4f9b\u3059\u308b<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Inertia.js\u306f\u3001\u3053\u308c\u3089\u306e\u8ab2\u984c\u306b\u5bfe\u3057\u3066\u9769\u65b0\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63d0\u4f9b\u3057\u307e\u3059\uff1a<\/p>\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=\"\">\/\/ \u5f93\u6765\u306eAPI\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\nclass UserController extends Controller\n{\n    public function index()\n    {\n        return response()-&gt;json([\n            'users' =&gt; User::all()\n        ]);\n    }\n}\n\n\/\/ Inertia\u3092\u4f7f\u7528\u3057\u305f\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\nclass UserController extends Controller\n{\n    public function index()\n    {\n        return Inertia::render('Users\/Index', [\n            'users' =&gt; User::all()\n        ]);\n    }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inertia.js\u306e\u4e3b\u306a\u7279\u5fb4\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e2\u30ce\u30ea\u30b7\u30c3\u30af\u306a\u30a2\u30d7\u30ed\u30fc\u30c1<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d0\u30fc\u30b5\u30a4\u30c9\u3068\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b5\u30a4\u30c9\u3092\u7d71\u5408\u7684\u306b\u6271\u3048\u308b<\/li>\n\n\n\n<li>\u5f93\u6765\u306eMVC\u30d1\u30bf\u30fc\u30f3\u3092\u8e0f\u8972\u3057\u3064\u3064SPA\u3092\u5b9f\u73fe<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b7\u30f3\u30d7\u30eb\u306a\u30c7\u30fc\u30bf\u53d7\u3051\u6e21\u3057<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP\u306e\u914d\u5217\u3092\u305d\u306e\u307e\u307eProps\u3068\u3057\u3066\u6e21\u305b\u308b<\/li>\n\n\n\n<li>\u578b\u306e\u81ea\u52d5\u5909\u63db\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u52b9\u7387\u7684\u306a\u30da\u30fc\u30b8\u9077\u79fb<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>XHR\u3092\u4f7f\u7528\u3057\u305f\u9ad8\u901f\u306a\u30da\u30fc\u30b8\u9077\u79fb<\/li>\n\n\n\n<li>\u5fc5\u8981\u306a\u30c7\u30fc\u30bf\u306e\u307f\u3092\u66f4\u65b0\u3059\u308b\u5dee\u5206\u66f4\u65b0<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">Laravel\u00d7Inertia \u306e\u7d44\u307f\u5408\u308f\u305b\u304c\u3082\u305f\u3089\u3059\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel\u3068Inertia\u306e\u7d44\u307f\u5408\u308f\u305b\u306f\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u5927\u304d\u306a\u30e1\u30ea\u30c3\u30c8\u3092\u3082\u305f\u3089\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u52b9\u7387\u306e\u5411\u4e0a<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Laravel Breeze\u306b\u3088\u308b\u7c21\u5358\u306a\u5c0e\u5165<\/li>\n\n\n\n<li>\u65e2\u5b58\u306eLaravel\u30b9\u30ad\u30eb\u30bb\u30c3\u30c8\u3092\u6d3b\u304b\u305b\u308b<\/li>\n\n\n\n<li>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\uff08Vue.js\/React\uff09\u3068\u306e\u89aa\u548c\u6027<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u5411\u4e0a<\/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=\"\">   \/\/ CSRF\u30c8\u30fc\u30af\u30f3\u306e\u81ea\u52d5\u51e6\u7406\n   Inertia::share('csrf_token', csrf_token());\n\n   \/\/ \u8a8d\u8a3c\u72b6\u614b\u306e\u5171\u6709\n   Inertia::share([\n       'auth' =&gt; function () {\n           return [\n               'user' =&gt; Auth::user() ? [\n                   'id' =&gt; Auth::user()-&gt;id,\n                   'name' =&gt; Auth::user()-&gt;name,\n               ] : null\n           ];\n       }\n   ]);<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u4fdd\u5b88\u6027\u306e\u5411\u4e0a<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5358\u4e00\u306e\u30b3\u30fc\u30c9\u30d9\u30fc\u30b9\u3067\u306e\u7ba1\u7406<\/li>\n\n\n\n<li>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u518d\u5229\u7528\u6027<\/li>\n\n\n\n<li>\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u7c21\u7d20\u5316<\/li>\n<\/ul>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d0\u30fc\u30b5\u30a4\u30c9\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u306e\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>\u52b9\u7387\u7684\u306a\u30a2\u30bb\u30c3\u30c8\u7ba1\u7406<\/li>\n\n\n\n<li>\u30ec\u30b9\u30dd\u30f3\u30b9\u30b5\u30a4\u30ba\u306e\u6700\u9069\u5316<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Inertia\u306f\u3001SPA\u306e\u5229\u70b9\u3092\u6d3b\u304b\u3057\u3064\u3064\u3001\u5f93\u6765\u306e\u30b5\u30fc\u30d0\u30fc\u30b5\u30a4\u30c9\u306e\u958b\u767a\u624b\u6cd5\u306e\u5229\u70b9\u3082\u53d6\u308a\u5165\u308c\u305f\u3001\u30d0\u30e9\u30f3\u30b9\u306e\u53d6\u308c\u305f\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002\u7279\u306bLaravel\u3068\u306e\u7d44\u307f\u5408\u308f\u305b\u3067\u306f\u3001\u958b\u767a\u8005\u306e\u751f\u7523\u6027\u3092\u5927\u304d\u304f\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">\u74b0\u5883\u69cb\u7bc9\u304b\u3089\u59cb\u3081\u308bLaravel Inertia<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u5fc5\u8981\u306a\u958b\u767a\u74b0\u5883\u3068\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u78ba\u8a8d<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel Inertia\u3092\u4f7f\u7528\u3059\u308b\u305f\u3081\u306e\u74b0\u5883\u8981\u4ef6\u3092\u78ba\u8a8d\u3057\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5fc5\u9808\u30b7\u30b9\u30c6\u30e0\u8981\u4ef6<\/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.0\u4ee5\u4e0a<\/li>\n\n\n\n<li>Node.js 16.0\u4ee5\u4e0a<\/li>\n\n\n\n<li>npm 8.0\u4ee5\u4e0a\u307e\u305f\u306fyarn 1.22\u4ee5\u4e0a<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u63a8\u5968\u30d6\u30e9\u30a6\u30b6\u8981\u4ef6<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Chrome \u6700\u65b0\u7248<\/li>\n\n\n\n<li>Firefox \u6700\u65b0\u7248<\/li>\n\n\n\n<li>Safari \u6700\u65b0\u7248<\/li>\n\n\n\n<li>Edge \u6700\u65b0\u7248<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u30c4\u30fc\u30eb<\/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=\"\">   # PHP\u62e1\u5f35\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u78ba\u8a8d\n   php -m | grep -E \"openssl|pdo|mbstring|tokenizer|xml|ctype|json\"\n\n   # Composer\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\n   composer --version\n\n   # Node.js\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\n   node --version\n\n   # npm\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d\n   npm --version<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">Laravel Breeze\u306b\u3088\u308bInertia\u5c0e\u5165\u624b\u9806<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u65b0\u898fLaravel\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210<\/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=\"\">   # \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\n   composer create-project laravel\/laravel your-app\n\n   # \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u79fb\u52d5\n   cd your-app\n\n   # \u4f9d\u5b58\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   composer install<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Laravel Breeze\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\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=\"\">   # Breeze\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   composer require laravel\/breeze --dev\n\n   # Inertia\u7248Breeze\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\uff08Vue\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\uff09\n   php artisan breeze:install vue\n\n   # \u307e\u305f\u306f\u3001React\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\n   php artisan breeze:install react\n\n   # \u5fc5\u8981\u306anpm\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n   npm install\n\n   # \u30a2\u30bb\u30c3\u30c8\u306e\u30d3\u30eb\u30c9\n   npm run dev<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\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=\"\">   \/\/ .env\u30d5\u30a1\u30a4\u30eb\u306e\u8a2d\u5b9a\u4f8b\n   DB_CONNECTION=mysql\n   DB_HOST=127.0.0.1\n   DB_PORT=3306\n   DB_DATABASE=your_database\n   DB_USERNAME=your_username\n   DB_PASSWORD=your_password\n\n   \/\/ \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u884c\n   php artisan migrate<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">Vue.js\/React\u5bfe\u5fdc\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Vue\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u57fa\u672c\u69cb\u9020\uff08app.js\u306e\u8a2d\u5b9a\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=\"\">   import { createApp, h } from 'vue'\n   import { createInertiaApp } from '@inertiajs\/vue3'\n\n   createInertiaApp({\n     resolve: name =&gt; {\n       const pages = import.meta.glob('.\/Pages\/**\/*.vue', { eager: true })\n       return pages[`.\/Pages\/${name}.vue`]\n     },\n     setup({ el, App, props, plugin }) {\n       createApp({ render: () =&gt; h(App, props) })\n         .use(plugin)\n         .mount(el)\n     },\n   })<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>React\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u57fa\u672c\u69cb\u9020\uff08app.js\u306e\u8a2d\u5b9a\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=\"\">   import { createInertiaApp } from '@inertiajs\/react'\n   import { createRoot } from 'react-dom\/client'\n\n   createInertiaApp({\n     resolve: name =&gt; {\n       const pages = import.meta.glob('.\/Pages\/**\/*.jsx', { eager: true })\n       return pages[`.\/Pages\/${name}.jsx`]\n     },\n     setup({ el, App, props }) {\n       createRoot(el).render(&lt;App {...props} \/&gt;)\n     },\n   })<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u5171\u901a\u306e\u8a2d\u5b9a\u3068\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/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\/HandleInertiaRequests.php\n\n   public function share(Request $request): array\n   {\n       return array_merge(parent::share($request), [\n           \/\/ \u30b0\u30ed\u30fc\u30d0\u30eb\u3067\u5171\u6709\u3057\u305f\u3044\u30c7\u30fc\u30bf\u3092\u5b9a\u7fa9\n           'auth' =&gt; [\n               'user' =&gt; $request-&gt;user() ? [\n                   'id' =&gt; $request-&gt;user()-&gt;id,\n                   'name' =&gt; $request-&gt;user()-&gt;name,\n                   'email' =&gt; $request-&gt;user()-&gt;email,\n               ] : null,\n           ],\n           'flash' =&gt; [\n               'message' =&gt; fn () =&gt; $request-&gt;session()-&gt;get('message')\n           ],\n       ]);\n   }<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u958b\u767a\u74b0\u5883\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=\"\">   # Vite\u306e\u958b\u767a\u30b5\u30fc\u30d0\u30fc\u8d77\u52d5\n   npm run dev\n\n   # \u672c\u756a\u7528\u30d3\u30eb\u30c9\n   npm run build<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u306e\u74b0\u5883\u69cb\u7bc9\u304c\u5b8c\u4e86\u3059\u308b\u3068\u3001\u4ee5\u4e0b\u306e\u6a5f\u80fd\u304c\u5229\u7528\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SPA\u30e9\u30a4\u30af\u306a\u30da\u30fc\u30b8\u9077\u79fb<\/li>\n\n\n\n<li>Laravel\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u3068\u306e\u7d71\u5408<\/li>\n\n\n\n<li>Vite\u7d4c\u7531\u306e\u30db\u30c3\u30c8\u30ea\u30ed\u30fc\u30c9<\/li>\n\n\n\n<li>TypeScript\u30b5\u30dd\u30fc\u30c8\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09<\/li>\n\n\n\n<li>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30d9\u30fc\u30b9\u306e\u958b\u767a<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u958b\u767a\u3092\u59cb\u3081\u308b\u524d\u306b\u3001\u4ee5\u4e0b\u306e\u52d5\u4f5c\u78ba\u8a8d\u3092\u884c\u3046\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ed\u30b0\u30a4\u30f3\/\u767b\u9332\u6a5f\u80fd\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30da\u30fc\u30b8\u9077\u79fb\u306e\u52d5\u4f5c\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30a2\u30bb\u30c3\u30c8\u306e\u8aad\u307f\u8fbc\u307f\u78ba\u8a8d<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001\u5b9f\u969b\u306e\u958b\u767a\u3092\u30b9\u30e0\u30fc\u30ba\u306b\u9032\u3081\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-8\">Inertia\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u30de\u30b9\u30bf\u30fc<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3068\u30d3\u30e5\u30fc\u306e\u9023\u643a\u65b9\u6cd5<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Laravel\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304b\u3089Inertia\u30d3\u30e5\u30fc\u3078\u306e\u30c7\u30fc\u30bf\u53d7\u3051\u6e21\u3057\u306f\u3001\u76f4\u611f\u7684\u3067\u7c21\u5358\u3067\u3059\u3002\u4ee5\u4e0b\u306b\u4e3b\u8981\u306a\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u793a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u57fa\u672c\u7684\u306a\u30da\u30fc\u30b8\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0<\/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\/TaskController.php\n   class TaskController extends Controller\n   {\n       public function index()\n       {\n           return Inertia::render('Tasks\/Index', [\n               'tasks' =&gt; Task::all()-&gt;map(fn($task) =&gt; [\n                   'id' =&gt; $task-&gt;id,\n                   'title' =&gt; $task-&gt;title,\n                   'completed' =&gt; $task-&gt;completed\n               ])\n           ]);\n       }\n\n       public function show(Task $task)\n       {\n           return Inertia::render('Tasks\/Show', [\n               'task' =&gt; $task-&gt;load('user', 'comments')\n           ]);\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30da\u30fc\u30b8\u30cd\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=\"\">   public function index()\n   {\n       return Inertia::render('Tasks\/Index', [\n           'tasks' =&gt; Task::query()\n               -&gt;when(Request::input('search'), function ($query, $search) {\n                   $query-&gt;where('title', 'like', \"%{$search}%\");\n               })\n               -&gt;paginate(10)\n               -&gt;withQueryString()\n               -&gt;through(fn($task) =&gt; [\n                   'id' =&gt; $task-&gt;id,\n                   'title' =&gt; $task-&gt;title,\n               ]),\n           'filters' =&gt; Request::only(['search']),\n       ]);\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u30d7\u30ed\u30c3\u30d7\u30b9\u3092\u6d3b\u7528\u3057\u305f\u30c7\u30fc\u30bf\u53d7\u3051\u6e21\u3057<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Vue\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u306e\u30d7\u30ed\u30c3\u30d7\u30b9\u53d7\u3051\u53d6\u308a<\/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=\"\">   &lt;!-- resources\/js\/Pages\/Tasks\/Index.vue --&gt;\n   &lt;script setup&gt;\n   import { ref } from 'vue'\n   import Layout from '@\/Layouts\/AppLayout.vue'\n\n   \/\/ \u30d7\u30ed\u30c3\u30d7\u30b9\u306e\u5b9a\u7fa9\n   defineProps({\n       tasks: {\n           type: Object,\n           required: true\n       },\n       filters: {\n           type: Object,\n           required: true\n       }\n   })\n\n   \/\/ \u691c\u7d22\u30d5\u30a9\u30fc\u30e0\u306e\u72b6\u614b\u7ba1\u7406\n   const search = ref(filters.search)\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;Layout&gt;\n           &lt;div class=\"container mx-auto py-8\"&gt;\n               &lt;!-- \u691c\u7d22\u30d5\u30a9\u30fc\u30e0 --&gt;\n               &lt;div class=\"mb-4\"&gt;\n                   &lt;input\n                       v-model=\"search\"\n                       type=\"text\"\n                       placeholder=\"\u30bf\u30b9\u30af\u3092\u691c\u7d22...\"\n                       class=\"border p-2 rounded\"\n                       @input=\"$inertia.get('\/tasks', { search }, {\n                           preserveState: true,\n                           replace: true\n                       })\"\n                   &gt;\n               &lt;\/div&gt;\n\n               &lt;!-- \u30bf\u30b9\u30af\u30ea\u30b9\u30c8 --&gt;\n               &lt;div v-for=\"task in tasks.data\" :key=\"task.id\"&gt;\n                   &lt;h3&gt;{{ task.title }}&lt;\/h3&gt;\n               &lt;\/div&gt;\n\n               &lt;!-- \u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3 --&gt;\n               &lt;pagination :links=\"tasks.links\" \/&gt;\n           &lt;\/div&gt;\n       &lt;\/Layout&gt;\n   &lt;\/template&gt;<\/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\u30d7\u30ed\u30c3\u30d7\u30b9\u53d7\u3051\u53d6\u308a<\/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\/Pages\/Tasks\/Index.jsx\n   import { useState } from 'react'\n   import Layout from '@\/Layouts\/AppLayout'\n   import { router } from '@inertiajs\/react'\n\n   export default function Index({ tasks, filters }) {\n       const [search, setSearch] = useState(filters.search)\n\n       const handleSearch = (e) =&gt; {\n           setSearch(e.target.value)\n           router.get('\/tasks', { search: e.target.value }, {\n               preserveState: true,\n               replace: true\n           })\n       }\n\n       return (\n           &lt;Layout&gt;\n               &lt;div className=\"container mx-auto py-8\"&gt;\n                   &lt;input\n                       value={search}\n                       onChange={handleSearch}\n                       type=\"text\"\n                       placeholder=\"\u30bf\u30b9\u30af\u3092\u691c\u7d22...\"\n                       className=\"border p-2 rounded\"\n                   \/&gt;\n\n                   {tasks.data.map(task =&gt; (\n                       &lt;div key={task.id}&gt;\n                           &lt;h3&gt;{task.title}&lt;\/h3&gt;\n                       &lt;\/div&gt;\n                   ))}\n\n                   &lt;Pagination links={tasks.links} \/&gt;\n               &lt;\/div&gt;\n           &lt;\/Layout&gt;\n       )\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u30da\u30fc\u30b8\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u4f5c\u6210\u3068\u7ba1\u7406<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5171\u901a\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u4f5c\u6210<\/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=\"\">   &lt;!-- resources\/js\/Layouts\/AppLayout.vue --&gt;\n   &lt;script setup&gt;\n   import { Link } from '@inertiajs\/vue3'\n   import { usePage } from '@inertiajs\/vue3'\n\n   const page = usePage()\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;div&gt;\n           &lt;nav class=\"bg-gray-800 text-white p-4\"&gt;\n               &lt;div class=\"container mx-auto flex justify-between\"&gt;\n                   &lt;Link href=\"\/\" class=\"font-bold\"&gt;\n                       \u30a2\u30d7\u30ea\u540d\n                   &lt;\/Link&gt;\n\n                   &lt;div v-if=\"page.props.auth.user\"&gt;\n                       &lt;span&gt;{{ page.props.auth.user.name }}&lt;\/span&gt;\n                       &lt;Link\n                           href=\"\/logout\"\n                           method=\"post\"\n                           as=\"button\"\n                           class=\"ml-4\"\n                       &gt;\n                           \u30ed\u30b0\u30a2\u30a6\u30c8\n                       &lt;\/Link&gt;\n                   &lt;\/div&gt;\n               &lt;\/div&gt;\n           &lt;\/nav&gt;\n\n           &lt;main&gt;\n               &lt;slot \/&gt;\n           &lt;\/main&gt;\n       &lt;\/div&gt;\n   &lt;\/template&gt;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u5171\u901a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u4f5c\u6210<\/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=\"\">   &lt;!-- resources\/js\/Components\/Button.vue --&gt;\n   &lt;script setup&gt;\n   defineProps({\n       type: {\n           type: String,\n           default: 'submit'\n       },\n       disabled: {\n           type: Boolean,\n           default: false\n       }\n   })\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;button\n           :type=\"type\"\n           :disabled=\"disabled\"\n           class=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50\"\n       &gt;\n           &lt;slot \/&gt;\n       &lt;\/button&gt;\n   &lt;\/template&gt;<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d5\u30a9\u30fc\u30e0\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=\"\">   &lt;!-- resources\/js\/Components\/TaskForm.vue --&gt;\n   &lt;script setup&gt;\n   import { useForm } from '@inertiajs\/vue3'\n   import Button from '@\/Components\/Button.vue'\n\n   const form = useForm({\n       title: '',\n       description: '',\n       due_date: null\n   })\n\n   const submit = () =&gt; {\n       form.post('\/tasks', {\n           onSuccess: () =&gt; {\n               form.reset()\n           }\n       })\n   }\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;form @submit.prevent=\"submit\" class=\"space-y-4\"&gt;\n           &lt;div&gt;\n               &lt;label class=\"block\"&gt;\u30bf\u30a4\u30c8\u30eb&lt;\/label&gt;\n               &lt;input\n                   v-model=\"form.title\"\n                   type=\"text\"\n                   class=\"w-full border p-2 rounded\"\n                   :class=\"{ 'border-red-500': form.errors.title }\"\n               &gt;\n               &lt;div v-if=\"form.errors.title\" class=\"text-red-500 text-sm\"&gt;\n                   {{ form.errors.title }}\n               &lt;\/div&gt;\n           &lt;\/div&gt;\n\n           &lt;div&gt;\n               &lt;label class=\"block\"&gt;\u8aac\u660e&lt;\/label&gt;\n               &lt;textarea\n                   v-model=\"form.description\"\n                   class=\"w-full border p-2 rounded\"\n                   :class=\"{ 'border-red-500': form.errors.description }\"\n               \/&gt;\n               &lt;div v-if=\"form.errors.description\" class=\"text-red-500 text-sm\"&gt;\n                   {{ form.errors.description }}\n               &lt;\/div&gt;\n           &lt;\/div&gt;\n\n           &lt;Button :disabled=\"form.processing\"&gt;\n               \u4fdd\u5b58\n           &lt;\/Button&gt;\n       &lt;\/form&gt;\n   &lt;\/template&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u5229\u70b9\u304c\u5f97\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u4e00\u8cab\u6027\u306e\u3042\u308bUI\/UX\u306e\u63d0\u4f9b<\/li>\n\n\n\n<li>\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u958b\u767a\u52b9\u7387\u306e\u5411\u4e0a<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u307e\u305f\u3001\u4ee5\u4e0b\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u610f\u8b58\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306f\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247\u306b\u5f93\u3063\u3066\u8a2d\u8a08\u3059\u308b<\/li>\n\n\n\n<li>\u30d7\u30ed\u30c3\u30d7\u30b9\u306e\u578b\u5b9a\u7fa9\u3092\u9069\u5207\u306b\u884c\u3046<\/li>\n\n\n\n<li>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u9593\u306e\u4f9d\u5b58\u95a2\u4fc2\u3092\u6700\u5c0f\u9650\u306b\u6291\u3048\u308b<\/li>\n\n\n\n<li>\u5171\u901a\u306e\u30b9\u30bf\u30a4\u30eb\u3084\u30e6\u30fc\u30c6\u30a3\u30ea\u30c6\u30a3\u3092\u6d3b\u7528\u3059\u308b<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u8a2d\u8a08\u3092\u884c\u3046<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">\u5b9f\u8df5\u7684\u306aInertia\u6d3b\u7528\u30c6\u30af\u30cb\u30c3\u30af<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30d5\u30a9\u30fc\u30e0\u51e6\u7406\u3068\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\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\/StoreTaskRequest.php\n   class StoreTaskRequest extends FormRequest\n   {\n       public function rules()\n       {\n           return [\n               'title' =&gt; ['required', 'string', 'max:255'],\n               'description' =&gt; ['nullable', 'string'],\n               'due_date' =&gt; ['required', 'date', 'after:today'],\n               'attachments.*' =&gt; ['file', 'max:10240', 'mimes:pdf,doc,docx'],\n           ];\n       }\n\n       public function messages()\n       {\n           return [\n               'title.required' =&gt; '\u30bf\u30a4\u30c8\u30eb\u306f\u5fc5\u9808\u3067\u3059',\n               'due_date.after' =&gt; '\u671f\u9650\u306f\u660e\u65e5\u4ee5\u964d\u306e\u65e5\u4ed8\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044',\n               'attachments.*.max' =&gt; '\u30d5\u30a1\u30a4\u30eb\u30b5\u30a4\u30ba\u306f10MB\u4ee5\u4e0b\u306b\u3057\u3066\u304f\u3060\u3055\u3044',\n           ];\n       }\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u9ad8\u5ea6\u306a\u30d5\u30a9\u30fc\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=\"\">   &lt;!-- resources\/js\/Components\/AdvancedTaskForm.vue --&gt;\n   &lt;script setup&gt;\n   import { useForm } from '@inertiajs\/vue3'\n   import { ref, watch } from 'vue'\n\n   const props = defineProps({\n       task: {\n           type: Object,\n           default: () =&gt; ({})\n       }\n   })\n\n   const form = useForm({\n       title: props.task?.title ?? '',\n       description: props.task?.description ?? '',\n       due_date: props.task?.due_date ?? null,\n       attachments: [],\n       _method: props.task?.id ? 'PUT' : 'POST'\n   })\n\n   const fileInput = ref(null)\n   const previewUrls = ref([])\n\n   \/\/ \u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u51e6\u7406\n   const handleFileUpload = (e) =&gt; {\n       const files = Array.from(e.target.files)\n       form.attachments = files\n\n       \/\/ \u30d7\u30ec\u30d3\u30e5\u30fcURL\u306e\u751f\u6210\n       previewUrls.value = files.map(file =&gt; URL.createObjectURL(file))\n   }\n\n   \/\/ \u30d5\u30a9\u30fc\u30e0\u9001\u4fe1\u51e6\u7406\n   const submit = () =&gt; {\n       const url = props.task?.id \n           ? `\/tasks\/${props.task.id}`\n           : '\/tasks'\n\n       form.post(url, {\n           onSuccess: () =&gt; {\n               form.reset()\n               previewUrls.value = []\n           },\n           preserveScroll: true\n       })\n   }\n\n   \/\/ \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\n   onBeforeUnmount(() =&gt; {\n       previewUrls.value.forEach(url =&gt; URL.revokeObjectURL(url))\n   })\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;form @submit.prevent=\"submit\" class=\"space-y-6\"&gt;\n           &lt;!-- \u30d5\u30a1\u30a4\u30eb\u30c9\u30ed\u30c3\u30d7\u30be\u30fc\u30f3 --&gt;\n           &lt;div\n               @drop.prevent=\"handleFileUpload\"\n               @dragover.prevent\n               class=\"border-2 border-dashed p-8 text-center\"\n           &gt;\n               &lt;input\n                   ref=\"fileInput\"\n                   type=\"file\"\n                   multiple\n                   class=\"hidden\"\n                   @change=\"handleFileUpload\"\n               &gt;\n               &lt;button\n                   type=\"button\"\n                   @click=\"fileInput.click()\"\n                   class=\"px-4 py-2 bg-gray-100 rounded\"\n               &gt;\n                   \u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\n               &lt;\/button&gt;\n           &lt;\/div&gt;\n\n           &lt;!-- \u30d5\u30a1\u30a4\u30eb\u30d7\u30ec\u30d3\u30e5\u30fc --&gt;\n           &lt;div v-if=\"previewUrls.length\" class=\"grid grid-cols-3 gap-4\"&gt;\n               &lt;div\n                   v-for=\"(url, index) in previewUrls\"\n                   :key=\"index\"\n                   class=\"relative\"\n               &gt;\n                   &lt;img\n                       :src=\"url\"\n                       class=\"w-full h-32 object-cover rounded\"\n                   &gt;\n                   &lt;button\n                       type=\"button\"\n                       @click=\"removeFile(index)\"\n                       class=\"absolute top-0 right-0 p-1 bg-red-500 text-white rounded-full\"\n                   &gt;\n                       \u00d7\n                   &lt;\/button&gt;\n               &lt;\/div&gt;\n           &lt;\/div&gt;\n       &lt;\/form&gt;\n   &lt;\/template&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">SPA\u3089\u3057\u3044\u753b\u9762\u9077\u79fb\u306e\u5b9f\u73fe\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d7\u30ed\u30b0\u30ec\u30b9\u30d0\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=\"\">   \/\/ resources\/js\/app.js\n   import { InertiaProgress } from '@inertiajs\/progress'\n\n   InertiaProgress.init({\n       color: '#4B5563',\n       showSpinner: true,\n       includeCSS: true,\n   })<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30da\u30fc\u30b8\u30c8\u30e9\u30f3\u30b8\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=\"\">   &lt;!-- resources\/js\/Layouts\/AppLayout.vue --&gt;\n   &lt;script setup&gt;\n   import { onMounted, ref } from 'vue'\n   import { router } from '@inertiajs\/vue3'\n\n   const isNavigating = ref(false)\n\n   onMounted(() =&gt; {\n       router.on('start', () =&gt; isNavigating.value = true)\n       router.on('finish', () =&gt; isNavigating.value = false)\n   })\n   &lt;\/script&gt;\n\n   &lt;template&gt;\n       &lt;div&gt;\n           &lt;Transition\n               enter-active-class=\"transition-opacity duration-300\"\n               enter-from-class=\"opacity-0\"\n               enter-to-class=\"opacity-100\"\n               leave-active-class=\"transition-opacity duration-300\"\n               leave-from-class=\"opacity-100\"\n               leave-to-class=\"opacity-0\"\n           &gt;\n               &lt;div\n                   v-if=\"isNavigating\"\n                   class=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center\"\n               &gt;\n                   &lt;div class=\"animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-white\"&gt;&lt;\/div&gt;\n               &lt;\/div&gt;\n           &lt;\/Transition&gt;\n\n           &lt;slot \/&gt;\n       &lt;\/div&gt;\n   &lt;\/template&gt;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u8a8d\u8a3c\u6a5f\u80fd\u306e\u7d71\u5408\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\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\/web.php\n   Route::middleware(['auth', 'verified'])-&gt;group(function () {\n       Route::get('\/dashboard', function () {\n           return Inertia::render('Dashboard');\n       })-&gt;name('dashboard');\n\n       Route::resource('tasks', TaskController::class);\n   });<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>CSRF\u30c8\u30fc\u30af\u30f3\u306e\u81ea\u52d5\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=\"\">   \/\/ app\/Http\/Middleware\/HandleInertiaRequests.php\n   public function share(Request $request): array\n   {\n       return array_merge(parent::share($request), [\n           'csrf_token' =&gt; csrf_token(),\n           'auth' =&gt; [\n               'user' =&gt; $request-&gt;user() ? [\n                   'id' =&gt; $request-&gt;user()-&gt;id,\n                   'name' =&gt; $request-&gt;user()-&gt;name,\n                   'email' =&gt; $request-&gt;user()-&gt;email,\n                   'permissions' =&gt; $request-&gt;user()-&gt;permissions,\n               ] : null,\n           ],\n           'flash' =&gt; [\n               'message' =&gt; fn () =&gt; $request-&gt;session()-&gt;get('message'),\n               'type' =&gt; fn () =&gt; $request-&gt;session()-&gt;get('type'),\n           ],\n       ]);\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u6a29\u9650\u7ba1\u7406\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\/Policies\/TaskPolicy.php\n   class TaskPolicy\n   {\n       public function viewAny(User $user): bool\n       {\n           return true;\n       }\n\n       public function view(User $user, Task $task): bool\n       {\n           return $user-&gt;id === $task-&gt;user_id || $user-&gt;hasRole('admin');\n       }\n\n       public function create(User $user): bool\n       {\n           return $user-&gt;hasPermissionTo('create tasks');\n       }\n\n       public function update(User $user, Task $task): bool\n       {\n           return $user-&gt;id === $task-&gt;user_id || $user-&gt;hasRole('admin');\n       }\n\n       public function delete(User $user, Task $task): bool\n       {\n           return $user-&gt;id === $task-&gt;user_id || $user-&gt;hasRole('admin');\n       }\n   }<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30ad\u30e5\u30a2\u306a\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\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=\"\">   \/\/ app\/Http\/Controllers\/TaskController.php\n   public function store(StoreTaskRequest $request)\n   {\n       $task = DB::transaction(function () use ($request) {\n           $task = Task::create([\n               'user_id' =&gt; $request-&gt;user()-&gt;id,\n               'title' =&gt; $request-&gt;title,\n               'description' =&gt; $request-&gt;description,\n               'due_date' =&gt; $request-&gt;due_date,\n           ]);\n\n           if ($request-&gt;hasFile('attachments')) {\n               foreach ($request-&gt;file('attachments') as $file) {\n                   $path = $file-&gt;store('task-attachments', 'private');\n                   $task-&gt;attachments()-&gt;create([\n                       'path' =&gt; $path,\n                       'original_name' =&gt; $file-&gt;getClientOriginalName(),\n                       'mime_type' =&gt; $file-&gt;getMimeType(),\n                       'size' =&gt; $file-&gt;getSize(),\n                   ]);\n               }\n           }\n\n           return $task;\n       });\n\n       return redirect()\n           -&gt;route('tasks.show', $task)\n           -&gt;with('message', '\u30bf\u30b9\u30af\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f');\n   }<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u3089\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u5229\u70b9\u304c\u5f97\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30bb\u30ad\u30e5\u30a2\u306a\u30d5\u30a9\u30fc\u30e0\u51e6\u7406<\/li>\n\n\n\n<li>\u30b9\u30e0\u30fc\u30ba\u306a\u753b\u9762\u9077\u79fb<\/li>\n\n\n\n<li>\u5805\u7262\u306a\u8a8d\u8a3c\u30fb\u8a8d\u53ef\u30b7\u30b9\u30c6\u30e0<\/li>\n\n\n\n<li>\u5b89\u5168\u306a\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u307e\u305f\u3001\u4ee5\u4e0b\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u5fc5\u305a\u8003\u616e\u3057\u3066\u304f\u3060\u3055\u3044\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5165\u529b\u5024\u306e\u5fb9\u5e95\u7684\u306a\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li>XSS\u5bfe\u7b56\u306e\u5b9f\u65bd<\/li>\n\n\n\n<li>CSRF\u5bfe\u7b56\u306e\u78ba\u5b9f\u306a\u5b9f\u88c5<\/li>\n\n\n\n<li>\u9069\u5207\u306a\u8a8d\u53ef\u5236\u5fa1\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-16\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u3068\u30c7\u30d0\u30c3\u30b0<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30a2\u30bb\u30c3\u30c8\u306e\u30d0\u30f3\u30c9\u30eb\u8a2d\u5b9a\u3068\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Vite\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=\"\">   \/\/ vite.config.js\n   import { defineConfig } from 'vite';\n   import laravel from 'laravel-vite-plugin';\n   import vue from '@vitejs\/plugin-vue';\n\n   export default defineConfig({\n       plugins: [\n           laravel({\n               input: ['resources\/js\/app.js'],\n               refresh: true,\n           }),\n           vue({\n               template: {\n                   transformAssetUrls: {\n                       base: null,\n                       includeAbsolute: false,\n                   },\n               },\n           }),\n       ],\n       build: {\n           \/\/ \u30c1\u30e3\u30f3\u30af\u30b5\u30a4\u30ba\u306e\u6700\u9069\u5316\n           chunkSizeWarningLimit: 1000,\n           rollupOptions: {\n               output: {\n                   manualChunks: {\n                       vendor: ['vue', '@inertiajs\/vue3'],\n                       \/\/ \u5171\u901a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u5206\u5272\n                       common: ['@\/Components\/Common'],\n                   },\n               },\n           },\n       },\n       optimizeDeps: {\n           include: ['@inertiajs\/vue3'],\n       },\n   });<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\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\/HandleInertiaRequests.php\n   public function version(Request $request): ?string\n   {\n       \/\/ \u30a2\u30bb\u30c3\u30c8\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u7ba1\u7406\n       return parent::version($request);\n   }\n\n   public function share(Request $request): array\n   {\n       return array_merge(parent::share($request), [\n           \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u30d0\u30b9\u30c6\u30a3\u30f3\u30b0\u306e\u305f\u3081\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u60c5\u5831\n           'asset_version' =&gt; config('app.asset_version'),\n           \/\/ \u30c7\u30fc\u30bf\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\n           'cached_data' =&gt; Cache::remember('global_data', 3600, function () {\n               return [\n                   'settings' =&gt; Setting::all(),\n                   'categories' =&gt; Category::all(),\n               ];\n           }),\n       ]);\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u9759\u7684\u30a2\u30bb\u30c3\u30c8\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\/filesystems.php\n   'disks' =&gt; [\n       'public' =&gt; [\n           'driver' =&gt; 'local',\n           'root' =&gt; public_path('storage'),\n           'url' =&gt; env('APP_URL').'\/storage',\n           'visibility' =&gt; 'public',\n           \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u30d8\u30c3\u30c0\u30fc\u306e\u8a2d\u5b9a\n           'headers' =&gt; [\n               'Cache-Control' =&gt; 'public, max-age=31536000',\n           ],\n       ],\n   ];<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">Lazy Loading\u306e\u3088\u3046\u306a\u52b9\u679c\u5b9f\u73fe\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u52d5\u7684\u30a4\u30f3\u30dd\u30fc\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\/Pages\/Tasks\/Index.vue\n   import { defineAsyncComponent } from 'vue'\n\n   \/\/ \u5927\u304d\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3092\u9045\u5ef6\u30ed\u30fc\u30c9\n   const TaskEditor = defineAsyncComponent(() =&gt;\n       import('@\/Components\/TaskEditor.vue')\n   )\n\n   \/\/ \u8907\u96d1\u306a\u30c1\u30e3\u30fc\u30c8\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3092\u9045\u5ef6\u30ed\u30fc\u30c9\n   const TaskAnalytics = defineAsyncComponent(() =&gt;\n       import('@\/Components\/TaskAnalytics.vue')\n   )<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30eb\u30fc\u30c8\u30d9\u30fc\u30b9\u306e\u5206\u5272<\/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\/app.js\n   createInertiaApp({\n       resolve: async (name) =&gt; {\n           \/\/ \u52d5\u7684\u30a4\u30f3\u30dd\u30fc\u30c8\u306b\u3088\u308b\u30b3\u30fc\u30c9\u5206\u5272\n           const pages = import.meta.glob('.\/Pages\/**\/*.vue')\n           return (await pages[`.\/Pages\/${name}.vue`]()).default\n       },\n       \/\/ ...\n   })<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30fc\u30bf\u306e\u9045\u5ef6\u30ed\u30fc\u30c9\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\/TaskController.php\n   public function index()\n   {\n       return Inertia::render('Tasks\/Index', [\n           'tasks' =&gt; Task::query()\n               -&gt;select(['id', 'title', 'status']) \/\/ \u5fc5\u8981\u306a\u9805\u76ee\u306e\u307f\u53d6\u5f97\n               -&gt;paginate(20)\n               -&gt;through(fn($task) =&gt; [\n                   'id' =&gt; $task-&gt;id,\n                   'title' =&gt; $task-&gt;title,\n                   'status' =&gt; $task-&gt;status,\n                   \/\/ \u8a73\u7d30\u30c7\u30fc\u30bf\u3078\u306eURL\u63d0\u4f9b\n                   'details_url' =&gt; route('tasks.details', $task),\n               ]),\n       ]);\n   }\n\n   public function details(Task $task)\n   {\n       \/\/ \u8a73\u7d30\u30c7\u30fc\u30bf\u3092\u975e\u540c\u671f\u3067\u53d6\u5f97\n       return response()-&gt;json([\n           'description' =&gt; $task-&gt;description,\n           'attachments' =&gt; $task-&gt;attachments,\n           'comments' =&gt; $task-&gt;comments()-&gt;with('user')-&gt;get(),\n       ]);\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u958b\u767a\u6642\u306e\u30c7\u30d0\u30c3\u30b0\u30c6\u30af\u30cb\u30c3\u30af\u3068\u30c4\u30fc\u30eb\u6d3b\u7528<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Inertia\u30c7\u30d0\u30c3\u30b0\u30c4\u30fc\u30eb\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\/app.js\n   import { createInertiaApp, plugin as InertiaPlugin } from '@inertiajs\/vue3'\n\n   if (process.env.NODE_ENV === 'development') {\n       const DevTools = await import('@inertiajs\/devtools').then(m =&gt; m.default)\n       createApp({ render: () =&gt; h(app, props) })\n           .use(InertiaPlugin)\n           .use(DevTools)\n           .mount(el)\n   }<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30c7\u30d0\u30c3\u30b0\u30d8\u30eb\u30d1\u30fc<\/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\/Helpers\/Debug.php\n   class Debug\n   {\n       public static function logInertiaRequest($request)\n       {\n           Log::channel('inertia')-&gt;info('Inertia Request', [\n               'url' =&gt; $request-&gt;url(),\n               'method' =&gt; $request-&gt;method(),\n               'data' =&gt; $request-&gt;all(),\n               'headers' =&gt; $request-&gt;headers-&gt;all(),\n           ]);\n       }\n\n       public static function logPerformance($operation, callable $callback)\n       {\n           $start = microtime(true);\n           $result = $callback();\n           $duration = microtime(true) - $start;\n\n           Log::channel('performance')-&gt;info(\"Performance Log: {$operation}\", [\n               'duration' =&gt; $duration,\n               'memory' =&gt; memory_get_peak_usage(true),\n           ]);\n\n           return $result;\n       }\n   }\n\n   \/\/ \u4f7f\u7528\u4f8b\n   public function index()\n   {\n       return Debug::logPerformance('Tasks Index', function () {\n           return Inertia::render('Tasks\/Index', [\n               'tasks' =&gt; Task::paginate(20),\n           ]);\n       });\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/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       if (config('app.debug')) {\n           DB::listen(function ($query) {\n               Log::channel('queries')-&gt;info('SQL Query', [\n                   'sql' =&gt; $query-&gt;sql,\n                   'bindings' =&gt; $query-&gt;bindings,\n                   'time' =&gt; $query-&gt;time,\n               ]);\n           });\n\n           Event::listen('inertia:start', function ($event) {\n               debug('Inertia request started');\n           });\n\n           Event::listen('inertia:finish', function ($event) {\n               debug('Inertia request finished');\n           });\n       }\n   }<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u9069\u5207\u306a\u5206\u5272<\/li>\n\n\n\n<li>\u4e0d\u8981\u306a\u30ea\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u306e\u9632\u6b62<\/li>\n\n\n\n<li>\u753b\u50cf\u306e\u6700\u9069\u5316\u3068Lazy Loading<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>N+1\u30af\u30a8\u30ea\u306e\u9632\u6b62<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u9069\u5207\u306a\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u5fc5\u8981\u306a\u30c7\u30fc\u30bf\u306e\u307f\u306e\u53d6\u5f97<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u76e3\u8996\u3068\u30c7\u30d0\u30c3\u30b0<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30e1\u30c8\u30ea\u30af\u30b9\u306e\u53ce\u96c6<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u30ed\u30b0\u306e\u9069\u5207\u306a\u7ba1\u7406<\/li>\n\n\n\n<li>\u30e6\u30fc\u30b6\u30fc\u4f53\u9a13\u306e\u76e3\u8996<\/li>\n\n\n\n<li>\u30c7\u30d0\u30c3\u30b0\u30c4\u30fc\u30eb\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">\u672c\u756a\u74b0\u5883\u3078\u306e\u5c55\u958b\u3068\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u672c\u756a\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=\"\">   # \u672c\u756a\u74b0\u5883\u7528\u306e.env\u8a2d\u5b9a\n   APP_ENV=production\n   APP_DEBUG=false\n\n   # \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u6700\u9069\u5316\n   php artisan config:cache\n   php artisan route:cache\n   php artisan view:cache\n\n   # \u30a2\u30bb\u30c3\u30c8\u306e\u30d3\u30eb\u30c9\n   npm run build<\/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   echo \"Starting deployment...\"\n\n   # \u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u5b9f\u884c\n   git pull origin main\n\n   # Composer\u306e\u4f9d\u5b58\u95a2\u4fc2\u66f4\u65b0\n   composer install --no-dev --optimize-autoloader\n\n   # \u74b0\u5883\u8a2d\u5b9a\n   cp .env.production .env\n   php artisan key:generate\n\n   # \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\n   php artisan migrate --force\n\n   # \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2\u3068\u518d\u751f\u6210\n   php artisan config:clear\n   php artisan cache:clear\n   php artisan view:clear\n   php artisan config:cache\n   php artisan route:cache\n   php artisan view:cache\n\n   # npm\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u30d3\u30eb\u30c9\n   npm ci\n   npm run build\n\n   # \u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u306e\u8a2d\u5b9a\n   chown -R www-data:www-data storage bootstrap\/cache\n   chmod -R 775 storage bootstrap\/cache\n\n   # \u30b5\u30fc\u30d3\u30b9\u306e\u518d\u8d77\u52d5\n   sudo supervisorctl restart all\n   sudo systemctl reload php8.1-fpm\n   sudo systemctl reload nginx\n\n   echo \"Deployment completed!\"<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>Nginx\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=\"\">   # \/etc\/nginx\/sites-available\/your-app.conf\n   server {\n       listen 80;\n       server_name your-domain.com;\n       root \/var\/www\/your-app\/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       # \u9759\u7684\u30a2\u30bb\u30c3\u30c8\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u8a2d\u5b9a\n       location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg)$ {\n           expires max;\n           log_not_found off;\n       }\n\n       location ~ \/\\.(?!well-known).* {\n           deny all;\n       }\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u7d99\u7d9a\u7684\u306a\u7d71\u5408\/\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u69cb\u7bc9<\/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\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@v2\n\n       - name: Setup PHP\n         uses: shivammathur\/setup-php@v2\n         with:\n           php-version: '8.1'\n\n       - name: Install Dependencies\n         run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist\n\n       - name: Setup Node.js\n         uses: actions\/setup-node@v2\n         with:\n           node-version: '16'\n\n       - name: Install NPM Dependencies\n         run: npm ci\n\n       - name: Build Assets\n         run: npm run build\n\n       - name: Execute Tests\n         run: vendor\/bin\/phpunit\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\/your-app\n             .\/deploy.sh<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u81ea\u52d5\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\/TaskTest.php\n   class TaskTest extends TestCase\n   {\n       use RefreshDatabase;\n\n       public function test_can_view_tasks()\n       {\n           $user = User::factory()-&gt;create();\n           $task = Task::factory()-&gt;create(['user_id' =&gt; $user-&gt;id]);\n\n           $response = $this-&gt;actingAs($user)\n               -&gt;get('\/tasks');\n\n           $response-&gt;assertInertia(fn (Assert $page) =&gt; $page\n               -&gt;component('Tasks\/Index')\n               -&gt;has('tasks.data', 1)\n               -&gt;where('tasks.data.0.id', $task-&gt;id)\n           );\n       }\n\n       public function test_can_create_task()\n       {\n           $user = User::factory()-&gt;create();\n\n           $response = $this-&gt;actingAs($user)\n               -&gt;post('\/tasks', [\n                   'title' =&gt; 'New Task',\n                   'description' =&gt; 'Task Description'\n               ]);\n\n           $response-&gt;assertRedirect();\n           $this-&gt;assertDatabaseHas('tasks', [\n               'title' =&gt; 'New Task',\n               'user_id' =&gt; $user-&gt;id\n           ]);\n       }\n   }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u6642\u306e\u6ce8\u610f\u70b9\u3068\u4e92\u63db\u6027\u7dad\u6301<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u306e\u78ba\u7acb<\/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\/version.php\n   return [\n       'current' =&gt; '1.0.0',\n       'minimum_php_version' =&gt; '8.1.0',\n       'minimum_laravel_version' =&gt; '10.0.0',\n       'update_scripts' =&gt; [\n           '1.0.0' =&gt; [\n               'migrate' =&gt; true,\n               'seed' =&gt; false,\n               'clear_cache' =&gt; true,\n               'custom_script' =&gt; 'App\\Updates\\Version100Update'\n           ]\n       ]\n   ];<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\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=\"\">   \/\/ app\/Console\/Commands\/UpdateApplication.php\n   class UpdateApplication extends Command\n   {\n       protected $signature = 'app:update';\n\n       public function handle()\n       {\n           \/\/ \u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u30e2\u30fc\u30c9\u306e\u958b\u59cb\n           $this-&gt;call('down');\n\n           try {\n               \/\/ \u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u306e\u4f5c\u6210\n               $this-&gt;call('backup:run');\n\n               \/\/ \u4f9d\u5b58\u95a2\u4fc2\u306e\u66f4\u65b0\n               $this-&gt;info('Updating dependencies...');\n               exec('composer update');\n               exec('npm update');\n\n               \/\/ \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\n               $this-&gt;call('migrate', ['--force' =&gt; true]);\n\n               \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u30af\u30ea\u30a2\n               $this-&gt;call('cache:clear');\n               $this-&gt;call('config:clear');\n               $this-&gt;call('view:clear');\n               $this-&gt;call('route:clear');\n\n               \/\/ \u30a2\u30bb\u30c3\u30c8\u306e\u518d\u30d3\u30eb\u30c9\n               exec('npm run build');\n\n               \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u518d\u751f\u6210\n               $this-&gt;call('config:cache');\n               $this-&gt;call('route:cache');\n               $this-&gt;call('view:cache');\n\n               $this-&gt;info('Update completed successfully!');\n           } catch (\\Exception $e) {\n               $this-&gt;error('Update failed: ' . $e-&gt;getMessage());\n               \/\/ \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u306e\u5b9f\u884c\n               $this-&gt;call('backup:restore', ['backup' =&gt; 'latest']);\n           } finally {\n               \/\/ \u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u30e2\u30fc\u30c9\u306e\u89e3\u9664\n               $this-&gt;call('up');\n           }\n       }\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u4e92\u63db\u6027\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP\/Laravel\/Node.js\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u306e\u5909\u66f4\u78ba\u8a8d<\/li>\n\n\n\n<li>\u4f9d\u5b58\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u4e92\u63db\u6027\u78ba\u8a8d<\/li>\n\n\n\n<li>API\u306e\u5f8c\u65b9\u4e92\u63db\u6027\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u4e92\u63db\u6027\u78ba\u8a8d<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5b9a\u671f\u7684\u306a\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u9069\u7528<\/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>\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u306e\u5b9f\u884c\u3068\u691c\u8a3c<\/li>\n\n\n\n<li>\u30ed\u30b0\u306e\u5b9a\u671f\u7684\u306a\u78ba\u8a8d<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u969c\u5bb3\u5bfe\u7b56<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u76e3\u8996\u30b7\u30b9\u30c6\u30e0\u306e\u5c0e\u5165<\/li>\n\n\n\n<li>\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u6226\u7565\u306e\u78ba\u7acb<\/li>\n\n\n\n<li>\u969c\u5bb3\u5fa9\u65e7\u624b\u9806\u306e\u6587\u66f8\u5316<\/li>\n\n\n\n<li>\u30a4\u30f3\u30b7\u30c7\u30f3\u30c8\u5bfe\u5fdc\u8a08\u753b\u306e\u7b56\u5b9a<\/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>\u8106\u5f31\u6027\u30b9\u30ad\u30e3\u30f3\u306e\u5b9a\u671f\u5b9f\u884c<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d1\u30c3\u30c1\u306e\u9069\u7528<\/li>\n\n\n\n<li>\u30a2\u30af\u30bb\u30b9\u30ed\u30b0\u306e\u76e3\u8996<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u76e3\u67fb\u306e\u5b9f\u65bd<\/li>\n<\/ul>\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":[12],"tags":[],"class_list":["post-2617","post","type-post","status-publish","format-standard","category-php","nothumb"],"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2617","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=2617"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2617\/revisions"}],"predecessor-version":[{"id":2619,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2617\/revisions\/2619"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}