[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KB6AE2CKSB1HPPMW5K6WV5":3,"skill-same:01M6KB6AE2CKSB1HPPMW5K6WV5":70},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":14,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M6KB6AE2CKSB1HPPMW5K6WV5","inertia-react-development",null,"Develops Inertia.js v3 React client-side applications. Activates when creating React pages, forms, or navigation; using \u003CLink>, \u003CForm>, useForm, useHttp, setLayoutProps, or router; working with deferred props, prefetching, optimistic updates, instant visits, or polling; or when user mentions React with Inertia, React pages, React forms, or React navigation.","imbasri\u002FlaraAI","imbasri","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F106748835?v=4","01M6KB1J0Q7VQ71CT93QS9FEMJ","Imam Basri","01M6KB1J4P9RQ4WZ6MNBW43X28",0,"MIT","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Finertia-react-development\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"development","inertia react development","inertia","react","js","laravel","instant","user","router","navigation","forms","pages","v3","link","client","form","applications","with","updates","2026-11-10 10:12:30",false,"---\nname: inertia-react-development\ndescription: \"Develops Inertia.js v3 React client-side applications. Activates when creating React pages, forms, or navigation; using \u003CLink>, \u003CForm>, useForm, useHttp, setLayoutProps, or router; working with deferred props, prefetching, optimistic updates, instant visits, or polling; or when user mentions React with Inertia, React pages, React forms, or React navigation.\"\nlicense: MIT\nmetadata:\n  author: laravel\n---\n\n# Inertia React Development\n\n## When to Apply\n\nActivate this skill when:\n\n- Creating or modifying React page components for Inertia\n- Working with forms in React (using `\u003CForm>`, `useForm`, or `useHttp`)\n- Implementing client-side navigation with `\u003CLink>` or `router`\n- Using v3 features: deferred props, prefetching, optimistic updates, instant visits, layout props, HTTP requests, WhenVisible, InfiniteScroll, once props, flash data, or polling\n- Building React-specific features with the Inertia protocol\n\n## Documentation\n\nUse `search-docs` for detailed Inertia v3 React patterns and documentation.\n\n## Basic Usage\n\n### Page Components Location\n\nReact page components should be placed in the `resources\u002Fjs\u002Fpages` directory.\n\n### Page Component Structure\n\n\u003C!-- Basic React Page Component -->\n```react\nexport default function UsersIndex({ users }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Users\u003C\u002Fh1>\n            \u003Cul>\n                {users.map(user => \u003Cli key={user.id}>{user.name}\u003C\u002Fli>)}\n            \u003C\u002Ful>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n## Client-Side Navigation\n\n### Basic Link Component\n\nUse `\u003CLink>` for client-side navigation instead of traditional `\u003Ca>` tags:\n\n\u003C!-- Inertia React Navigation -->\n```react\nimport { Link, router } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002F\">Home\u003C\u002FLink>\n\u003CLink href=\"\u002Fusers\">Users\u003C\u002FLink>\n\u003CLink href={`\u002Fusers\u002F${user.id}`}>View User\u003C\u002FLink>\n```\n\n### Link with Method\n\n\u003C!-- Link with POST Method -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Flogout\" method=\"post\" as=\"button\">\n    Logout\n\u003C\u002FLink>\n```\n\n### Prefetching\n\nPrefetch pages to improve perceived performance:\n\n\u003C!-- Prefetch on Hover -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Fusers\" prefetch>\n    Users\n\u003C\u002FLink>\n```\n\n### Programmatic Navigation\n\n\u003C!-- Router Visit -->\n```react\nimport { router } from '@inertiajs\u002Freact'\n\nfunction handleClick() {\n    router.visit('\u002Fusers')\n}\n\n\u002F\u002F Or with options\nrouter.visit('\u002Fusers', {\n    method: 'post',\n    data: { name: 'John' },\n    onSuccess: () => console.log('Success!'),\n})\n```\n\n## Form Handling\n\n### Form Component (Recommended)\n\nThe recommended way to build forms is with the `\u003CForm>` component:\n\n\u003C!-- Form Component Example -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\nexport default function CreateUser() {\n    return (\n        \u003CForm action=\"\u002Fusers\" method=\"post\">\n            {({ errors, processing, wasSuccessful }) => (\n                \u003C>\n                    \u003Cinput type=\"text\" name=\"name\" \u002F>\n                    {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n                    \u003Cinput type=\"email\" name=\"email\" \u002F>\n                    {errors.email && \u003Cdiv>{errors.email}\u003C\u002Fdiv>}\n\n                    \u003Cbutton type=\"submit\" disabled={processing}>\n                        {processing ? 'Creating...' : 'Create User'}\n                    \u003C\u002Fbutton>\n\n                    {wasSuccessful && \u003Cdiv>User created!\u003C\u002Fdiv>}\n                \u003C\u002F>\n            )}\n        \u003C\u002FForm>\n    )\n}\n```\n\n### Form Component With All Props\n\n\u003C!-- Form Component Full Example -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm action=\"\u002Fusers\" method=\"post\">\n    {({\n        errors,\n        hasErrors,\n        processing,\n        progress,\n        wasSuccessful,\n        recentlySuccessful,\n        clearErrors,\n        resetAndClearErrors,\n        defaults,\n        isDirty,\n        reset,\n        submit\n    }) => (\n        \u003C>\n            \u003Cinput type=\"text\" name=\"name\" defaultValue={defaults.name} \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                {processing ? 'Saving...' : 'Save'}\n            \u003C\u002Fbutton>\n\n            {progress && (\n                \u003Cprogress value={progress.percentage} max=\"100\">\n                    {progress.percentage}%\n                \u003C\u002Fprogress>\n            )}\n\n            {wasSuccessful && \u003Cdiv>Saved!\u003C\u002Fdiv>}\n        \u003C\u002F>\n    )}\n\u003C\u002FForm>\n```\n\n### Form Component Reset Props\n\nThe `\u003CForm>` component supports automatic resetting:\n\n- `resetOnError` - Reset form data when the request fails\n- `resetOnSuccess` - Reset form data when the request succeeds\n- `setDefaultsOnSuccess` - Update default values on success\n\nUse the `search-docs` tool with a query of `form component resetting` for detailed guidance.\n\n\u003C!-- Form with Reset Props -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm\n    action=\"\u002Fusers\"\n    method=\"post\"\n    resetOnSuccess\n    setDefaultsOnSuccess\n>\n    {({ errors, processing, wasSuccessful }) => (\n        \u003C>\n            \u003Cinput type=\"text\" name=\"name\" \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                Submit\n            \u003C\u002Fbutton>\n        \u003C\u002F>\n    )}\n\u003C\u002FForm>\n```\n\nForms can also be built using the `useForm` helper for more programmatic control. Use the `search-docs` tool with a query of `useForm helper` for guidance.\n\n### `useForm` Hook\n\nFor more programmatic control or to follow existing conventions, use the `useForm` hook:\n\n\u003C!-- useForm Hook Example -->\n```react\nimport { useForm } from '@inertiajs\u002Freact'\n\nexport default function CreateUser() {\n    const { data, setData, post, processing, errors, reset } = useForm({\n        name: '',\n        email: '',\n        password: '',\n    })\n\n    function submit(e) {\n        e.preventDefault()\n        post('\u002Fusers', {\n            onSuccess: () => reset('password'),\n        })\n    }\n\n    return (\n        \u003Cform onSubmit={submit}>\n            \u003Cinput\n                type=\"text\"\n                value={data.name}\n                onChange={e => setData('name', e.target.value)}\n            \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cinput\n                type=\"email\"\n                value={data.email}\n                onChange={e => setData('email', e.target.value)}\n            \u002F>\n            {errors.email && \u003Cdiv>{errors.email}\u003C\u002Fdiv>}\n\n            \u003Cinput\n                type=\"password\"\n                value={data.password}\n                onChange={e => setData('password', e.target.value)}\n            \u002F>\n            {errors.password && \u003Cdiv>{errors.password}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                Create User\n            \u003C\u002Fbutton>\n        \u003C\u002Fform>\n    )\n}\n```\n\n## Inertia v3 Features\n\n### HTTP Requests\n\nUse the `useHttp` hook for standalone HTTP requests that do not trigger Inertia page visits. It provides the same developer experience as `useForm`, but for plain JSON endpoints.\n\n\u003C!-- useHttp Example -->\n```react\nimport { useHttp } from '@inertiajs\u002Freact'\n\nexport default function Search() {\n    const { data, setData, get, processing } = useHttp({\n        query: '',\n    })\n\n    function search(e) {\n        setData('query', e.target.value)\n        get('\u002Fapi\u002Fsearch', {\n            onSuccess: (response) => {\n                console.log(response)\n            },\n        })\n    }\n\n    return (\n        \u003C>\n            \u003Cinput value={data.query} onChange={search} \u002F>\n            {processing && \u003Cdiv>Searching...\u003C\u002Fdiv>}\n        \u003C\u002F>\n    )\n}\n```\n\n### Optimistic Updates\n\nApply data changes instantly before the server responds, with automatic rollback on failure:\n\n\u003C!-- Optimistic Update with Router -->\n```react\nimport { router } from '@inertiajs\u002Freact'\n\nfunction like(post) {\n    router.optimistic((props) => ({\n        post: {\n            ...props.post,\n            likes: props.post.likes + 1,\n        },\n    })).post(`\u002Fposts\u002F${post.id}\u002Flike`)\n}\n```\n\nOptimistic updates also work with `useForm` and the `\u003CForm>` component:\n\n\u003C!-- Optimistic Update with Form Component -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm\n    action=\"\u002Ftodos\"\n    method=\"post\"\n    optimistic={(props, data) => ({\n        todos: [...props.todos, { id: Date.now(), name: data.name, done: false }],\n    })}\n>\n    \u003Cinput type=\"text\" name=\"name\" \u002F>\n    \u003Cbutton type=\"submit\">Add Todo\u003C\u002Fbutton>\n\u003C\u002FForm>\n```\n\n### Instant Visits\n\nNavigate to a new page immediately without waiting for the server response. The target component renders right away with shared props, while page-specific props load in the background.\n\n\u003C!-- Instant Visit with Link -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Fdashboard\" component=\"Dashboard\">Dashboard\u003C\u002FLink>\n\n\u003CLink\n    href=\"\u002Fposts\u002F1\"\n    component=\"Posts\u002FShow\"\n    pageProps={{ post: { id: 1, title: 'My Post' } }}\n>\n    View Post\n\u003C\u002FLink>\n```\n\n### Layout Props\n\nShare dynamic data between pages and persistent layouts:\n\n\u003C!-- Layout Props in Layout -->\n```react\nexport default function Layout({ title = 'My App', showSidebar = true, children }) {\n    return (\n        \u003C>\n            \u003Cheader>{title}\u003C\u002Fheader>\n            {showSidebar && \u003Caside>Sidebar\u003C\u002Faside>}\n            \u003Cmain>{children}\u003C\u002Fmain>\n        \u003C\u002F>\n    )\n}\n```\n\n\u003C!-- Setting Layout Props from Page -->\n```react\nimport { setLayoutProps } from '@inertiajs\u002Freact'\n\nexport default function Dashboard() {\n    setLayoutProps({\n        title: 'Dashboard',\n        showSidebar: false,\n    })\n\n    return \u003Ch1>Dashboard\u003C\u002Fh1>\n}\n```\n\n### Deferred Props\n\nUse deferred props to load data after initial page render:\n\n\u003C!-- Deferred Props with Empty State -->\n```react\nexport default function UsersIndex({ users }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Users\u003C\u002Fh1>\n            {!users ? (\n                \u003Cdiv className=\"animate-pulse\">\n                    \u003Cdiv className=\"h-4 bg-gray-200 rounded w-3\u002F4 mb-2\">\u003C\u002Fdiv>\n                    \u003Cdiv className=\"h-4 bg-gray-200 rounded w-1\u002F2\">\u003C\u002Fdiv>\n                \u003C\u002Fdiv>\n            ) : (\n                \u003Cul>\n                    {users.map(user => (\n                        \u003Cli key={user.id}>{user.name}\u003C\u002Fli>\n                    ))}\n                \u003C\u002Ful>\n            )}\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n### Polling\n\nUse the `usePoll` hook to automatically refresh data at intervals. It handles cleanup on unmount and throttles polling when the tab is inactive.\n\n\u003C!-- Basic Polling -->\n```react\nimport { usePoll } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    usePoll(5000)\n\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n            \u003Cdiv>Active Users: {stats.activeUsers}\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n\u003C!-- Polling With Request Options and Manual Control -->\n```react\nimport { usePoll } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    const { start, stop } = usePoll(5000, {\n        only: ['stats'],\n        onStart() {\n            console.log('Polling request started')\n        },\n        onFinish() {\n            console.log('Polling request finished')\n        },\n    }, {\n        autoStart: false,\n        keepAlive: true,\n    })\n\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n            \u003Cdiv>Active Users: {stats.activeUsers}\u003C\u002Fdiv>\n            \u003Cbutton onClick={start}>Start Polling\u003C\u002Fbutton>\n            \u003Cbutton onClick={stop}>Stop Polling\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n- `autoStart` (default `true`) - set to `false` to start polling manually via the returned `start()` function\n- `keepAlive` (default `false`) - set to `true` to prevent throttling when the browser tab is inactive\n\n### WhenVisible\n\nLazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:\n\n\u003C!-- WhenVisible Example -->\n```react\nimport { WhenVisible } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n\n            \u003CWhenVisible data=\"stats\" buffer={200} fallback={\u003Cdiv className=\"animate-pulse\">Loading stats...\u003C\u002Fdiv>}>\n                {({ fetching }) => (\n                    \u003Cdiv>\n                        \u003Cp>Total Users: {stats.total_users}\u003C\u002Fp>\n                        \u003Cp>Revenue: {stats.revenue}\u003C\u002Fp>\n                        {fetching && \u003Cspan>Refreshing...\u003C\u002Fspan>}\n                    \u003C\u002Fdiv>\n                )}\n            \u003C\u002FWhenVisible>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n### InfiniteScroll\n\nAutomatically load additional pages of paginated data as users scroll:\n\n\u003C!-- InfiniteScroll Example -->\n```react\nimport { InfiniteScroll } from '@inertiajs\u002Freact'\n\nexport default function Users({ users }) {\n    return (\n        \u003CInfiniteScroll data=\"users\">\n            {users.data.map(user => (\n                \u003Cdiv key={user.id}>{user.name}\u003C\u002Fdiv>\n            ))}\n        \u003C\u002FInfiniteScroll>\n    )\n}\n```\n\nThe server must use `Inertia::scroll()` to configure the paginated data. Use the `search-docs` tool with a query of `infinite scroll` for detailed guidance on buffers, manual loading, reverse mode, and custom trigger elements.\n\n## Server-Side Patterns\n\nServer-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.\n\n## Common Pitfalls\n\n- Using traditional `\u003Ca>` links instead of Inertia's `\u003CLink>` component (breaks SPA behavior)\n- Forgetting to add loading states (skeleton screens) when using deferred props\n- Not handling the `undefined` state of deferred props before data loads\n- Using `\u003Cform>` without preventing default submission (use `\u003CForm>` component or `e.preventDefault()`)\n- Forgetting to check if `\u003CForm>` component is available in your Inertia version\n- Using `router.cancel()` instead of `router.cancelAll()` (v3 breaking change)\n- Using `router.on('invalid', ...)` or `router.on('exception', ...)` instead of the renamed `httpException` and `networkError` events","# Inertia React Development\n\n## When to Apply\n\nActivate this skill when:\n\n- Creating or modifying React page components for Inertia\n- Working with forms in React (using `\u003CForm>`, `useForm`, or `useHttp`)\n- Implementing client-side navigation with `\u003CLink>` or `router`\n- Using v3 features: deferred props, prefetching, optimistic updates, instant visits, layout props, HTTP requests, WhenVisible, InfiniteScroll, once props, flash data, or polling\n- Building React-specific features with the Inertia protocol\n\n## Documentation\n\nUse `search-docs` for detailed Inertia v3 React patterns and documentation.\n\n## Basic Usage\n\n### Page Components Location\n\nReact page components should be placed in the `resources\u002Fjs\u002Fpages` directory.\n\n### Page Component Structure\n\n\u003C!-- Basic React Page Component -->\n```react\nexport default function UsersIndex({ users }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Users\u003C\u002Fh1>\n            \u003Cul>\n                {users.map(user => \u003Cli key={user.id}>{user.name}\u003C\u002Fli>)}\n            \u003C\u002Ful>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n## Client-Side Navigation\n\n### Basic Link Component\n\nUse `\u003CLink>` for client-side navigation instead of traditional `\u003Ca>` tags:\n\n\u003C!-- Inertia React Navigation -->\n```react\nimport { Link, router } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002F\">Home\u003C\u002FLink>\n\u003CLink href=\"\u002Fusers\">Users\u003C\u002FLink>\n\u003CLink href={`\u002Fusers\u002F${user.id}`}>View User\u003C\u002FLink>\n```\n\n### Link with Method\n\n\u003C!-- Link with POST Method -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Flogout\" method=\"post\" as=\"button\">\n    Logout\n\u003C\u002FLink>\n```\n\n### Prefetching\n\nPrefetch pages to improve perceived performance:\n\n\u003C!-- Prefetch on Hover -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Fusers\" prefetch>\n    Users\n\u003C\u002FLink>\n```\n\n### Programmatic Navigation\n\n\u003C!-- Router Visit -->\n```react\nimport { router } from '@inertiajs\u002Freact'\n\nfunction handleClick() {\n    router.visit('\u002Fusers')\n}\n\n\u002F\u002F Or with options\nrouter.visit('\u002Fusers', {\n    method: 'post',\n    data: { name: 'John' },\n    onSuccess: () => console.log('Success!'),\n})\n```\n\n## Form Handling\n\n### Form Component (Recommended)\n\nThe recommended way to build forms is with the `\u003CForm>` component:\n\n\u003C!-- Form Component Example -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\nexport default function CreateUser() {\n    return (\n        \u003CForm action=\"\u002Fusers\" method=\"post\">\n            {({ errors, processing, wasSuccessful }) => (\n                \u003C>\n                    \u003Cinput type=\"text\" name=\"name\" \u002F>\n                    {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n                    \u003Cinput type=\"email\" name=\"email\" \u002F>\n                    {errors.email && \u003Cdiv>{errors.email}\u003C\u002Fdiv>}\n\n                    \u003Cbutton type=\"submit\" disabled={processing}>\n                        {processing ? 'Creating...' : 'Create User'}\n                    \u003C\u002Fbutton>\n\n                    {wasSuccessful && \u003Cdiv>User created!\u003C\u002Fdiv>}\n                \u003C\u002F>\n            )}\n        \u003C\u002FForm>\n    )\n}\n```\n\n### Form Component With All Props\n\n\u003C!-- Form Component Full Example -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm action=\"\u002Fusers\" method=\"post\">\n    {({\n        errors,\n        hasErrors,\n        processing,\n        progress,\n        wasSuccessful,\n        recentlySuccessful,\n        clearErrors,\n        resetAndClearErrors,\n        defaults,\n        isDirty,\n        reset,\n        submit\n    }) => (\n        \u003C>\n            \u003Cinput type=\"text\" name=\"name\" defaultValue={defaults.name} \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                {processing ? 'Saving...' : 'Save'}\n            \u003C\u002Fbutton>\n\n            {progress && (\n                \u003Cprogress value={progress.percentage} max=\"100\">\n                    {progress.percentage}%\n                \u003C\u002Fprogress>\n            )}\n\n            {wasSuccessful && \u003Cdiv>Saved!\u003C\u002Fdiv>}\n        \u003C\u002F>\n    )}\n\u003C\u002FForm>\n```\n\n### Form Component Reset Props\n\nThe `\u003CForm>` component supports automatic resetting:\n\n- `resetOnError` - Reset form data when the request fails\n- `resetOnSuccess` - Reset form data when the request succeeds\n- `setDefaultsOnSuccess` - Update default values on success\n\nUse the `search-docs` tool with a query of `form component resetting` for detailed guidance.\n\n\u003C!-- Form with Reset Props -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm\n    action=\"\u002Fusers\"\n    method=\"post\"\n    resetOnSuccess\n    setDefaultsOnSuccess\n>\n    {({ errors, processing, wasSuccessful }) => (\n        \u003C>\n            \u003Cinput type=\"text\" name=\"name\" \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                Submit\n            \u003C\u002Fbutton>\n        \u003C\u002F>\n    )}\n\u003C\u002FForm>\n```\n\nForms can also be built using the `useForm` helper for more programmatic control. Use the `search-docs` tool with a query of `useForm helper` for guidance.\n\n### `useForm` Hook\n\nFor more programmatic control or to follow existing conventions, use the `useForm` hook:\n\n\u003C!-- useForm Hook Example -->\n```react\nimport { useForm } from '@inertiajs\u002Freact'\n\nexport default function CreateUser() {\n    const { data, setData, post, processing, errors, reset } = useForm({\n        name: '',\n        email: '',\n        password: '',\n    })\n\n    function submit(e) {\n        e.preventDefault()\n        post('\u002Fusers', {\n            onSuccess: () => reset('password'),\n        })\n    }\n\n    return (\n        \u003Cform onSubmit={submit}>\n            \u003Cinput\n                type=\"text\"\n                value={data.name}\n                onChange={e => setData('name', e.target.value)}\n            \u002F>\n            {errors.name && \u003Cdiv>{errors.name}\u003C\u002Fdiv>}\n\n            \u003Cinput\n                type=\"email\"\n                value={data.email}\n                onChange={e => setData('email', e.target.value)}\n            \u002F>\n            {errors.email && \u003Cdiv>{errors.email}\u003C\u002Fdiv>}\n\n            \u003Cinput\n                type=\"password\"\n                value={data.password}\n                onChange={e => setData('password', e.target.value)}\n            \u002F>\n            {errors.password && \u003Cdiv>{errors.password}\u003C\u002Fdiv>}\n\n            \u003Cbutton type=\"submit\" disabled={processing}>\n                Create User\n            \u003C\u002Fbutton>\n        \u003C\u002Fform>\n    )\n}\n```\n\n## Inertia v3 Features\n\n### HTTP Requests\n\nUse the `useHttp` hook for standalone HTTP requests that do not trigger Inertia page visits. It provides the same developer experience as `useForm`, but for plain JSON endpoints.\n\n\u003C!-- useHttp Example -->\n```react\nimport { useHttp } from '@inertiajs\u002Freact'\n\nexport default function Search() {\n    const { data, setData, get, processing } = useHttp({\n        query: '',\n    })\n\n    function search(e) {\n        setData('query', e.target.value)\n        get('\u002Fapi\u002Fsearch', {\n            onSuccess: (response) => {\n                console.log(response)\n            },\n        })\n    }\n\n    return (\n        \u003C>\n            \u003Cinput value={data.query} onChange={search} \u002F>\n            {processing && \u003Cdiv>Searching...\u003C\u002Fdiv>}\n        \u003C\u002F>\n    )\n}\n```\n\n### Optimistic Updates\n\nApply data changes instantly before the server responds, with automatic rollback on failure:\n\n\u003C!-- Optimistic Update with Router -->\n```react\nimport { router } from '@inertiajs\u002Freact'\n\nfunction like(post) {\n    router.optimistic((props) => ({\n        post: {\n            ...props.post,\n            likes: props.post.likes + 1,\n        },\n    })).post(`\u002Fposts\u002F${post.id}\u002Flike`)\n}\n```\n\nOptimistic updates also work with `useForm` and the `\u003CForm>` component:\n\n\u003C!-- Optimistic Update with Form Component -->\n```react\nimport { Form } from '@inertiajs\u002Freact'\n\n\u003CForm\n    action=\"\u002Ftodos\"\n    method=\"post\"\n    optimistic={(props, data) => ({\n        todos: [...props.todos, { id: Date.now(), name: data.name, done: false }],\n    })}\n>\n    \u003Cinput type=\"text\" name=\"name\" \u002F>\n    \u003Cbutton type=\"submit\">Add Todo\u003C\u002Fbutton>\n\u003C\u002FForm>\n```\n\n### Instant Visits\n\nNavigate to a new page immediately without waiting for the server response. The target component renders right away with shared props, while page-specific props load in the background.\n\n\u003C!-- Instant Visit with Link -->\n```react\nimport { Link } from '@inertiajs\u002Freact'\n\n\u003CLink href=\"\u002Fdashboard\" component=\"Dashboard\">Dashboard\u003C\u002FLink>\n\n\u003CLink\n    href=\"\u002Fposts\u002F1\"\n    component=\"Posts\u002FShow\"\n    pageProps={{ post: { id: 1, title: 'My Post' } }}\n>\n    View Post\n\u003C\u002FLink>\n```\n\n### Layout Props\n\nShare dynamic data between pages and persistent layouts:\n\n\u003C!-- Layout Props in Layout -->\n```react\nexport default function Layout({ title = 'My App', showSidebar = true, children }) {\n    return (\n        \u003C>\n            \u003Cheader>{title}\u003C\u002Fheader>\n            {showSidebar && \u003Caside>Sidebar\u003C\u002Faside>}\n            \u003Cmain>{children}\u003C\u002Fmain>\n        \u003C\u002F>\n    )\n}\n```\n\n\u003C!-- Setting Layout Props from Page -->\n```react\nimport { setLayoutProps } from '@inertiajs\u002Freact'\n\nexport default function Dashboard() {\n    setLayoutProps({\n        title: 'Dashboard',\n        showSidebar: false,\n    })\n\n    return \u003Ch1>Dashboard\u003C\u002Fh1>\n}\n```\n\n### Deferred Props\n\nUse deferred props to load data after initial page render:\n\n\u003C!-- Deferred Props with Empty State -->\n```react\nexport default function UsersIndex({ users }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Users\u003C\u002Fh1>\n            {!users ? (\n                \u003Cdiv className=\"animate-pulse\">\n                    \u003Cdiv className=\"h-4 bg-gray-200 rounded w-3\u002F4 mb-2\">\u003C\u002Fdiv>\n                    \u003Cdiv className=\"h-4 bg-gray-200 rounded w-1\u002F2\">\u003C\u002Fdiv>\n                \u003C\u002Fdiv>\n            ) : (\n                \u003Cul>\n                    {users.map(user => (\n                        \u003Cli key={user.id}>{user.name}\u003C\u002Fli>\n                    ))}\n                \u003C\u002Ful>\n            )}\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n### Polling\n\nUse the `usePoll` hook to automatically refresh data at intervals. It handles cleanup on unmount and throttles polling when the tab is inactive.\n\n\u003C!-- Basic Polling -->\n```react\nimport { usePoll } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    usePoll(5000)\n\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n            \u003Cdiv>Active Users: {stats.activeUsers}\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n\u003C!-- Polling With Request Options and Manual Control -->\n```react\nimport { usePoll } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    const { start, stop } = usePoll(5000, {\n        only: ['stats'],\n        onStart() {\n            console.log('Polling request started')\n        },\n        onFinish() {\n            console.log('Polling request finished')\n        },\n    }, {\n        autoStart: false,\n        keepAlive: true,\n    })\n\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n            \u003Cdiv>Active Users: {stats.activeUsers}\u003C\u002Fdiv>\n            \u003Cbutton onClick={start}>Start Polling\u003C\u002Fbutton>\n            \u003Cbutton onClick={stop}>Stop Polling\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n- `autoStart` (default `true`) - set to `false` to start polling manually via the returned `start()` function\n- `keepAlive` (default `false`) - set to `true` to prevent throttling when the browser tab is inactive\n\n### WhenVisible\n\nLazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:\n\n\u003C!-- WhenVisible Example -->\n```react\nimport { WhenVisible } from '@inertiajs\u002Freact'\n\nexport default function Dashboard({ stats }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Dashboard\u003C\u002Fh1>\n\n            \u003CWhenVisible data=\"stats\" buffer={200} fallback={\u003Cdiv className=\"animate-pulse\">Loading stats...\u003C\u002Fdiv>}>\n                {({ fetching }) => (\n                    \u003Cdiv>\n                        \u003Cp>Total Users: {stats.total_users}\u003C\u002Fp>\n                        \u003Cp>Revenue: {stats.revenue}\u003C\u002Fp>\n                        {fetching && \u003Cspan>Refreshing...\u003C\u002Fspan>}\n                    \u003C\u002Fdiv>\n                )}\n            \u003C\u002FWhenVisible>\n        \u003C\u002Fdiv>\n    )\n}\n```\n\n### InfiniteScroll\n\nAutomatically load additional pages of paginated data as users scroll:\n\n\u003C!-- InfiniteScroll Example -->\n```react\nimport { InfiniteScroll } from '@inertiajs\u002Freact'\n\nexport default function Users({ users }) {\n    return (\n        \u003CInfiniteScroll data=\"users\">\n            {users.data.map(user => (\n                \u003Cdiv key={user.id}>{user.name}\u003C\u002Fdiv>\n            ))}\n        \u003C\u002FInfiniteScroll>\n    )\n}\n```\n\nThe server must use `Inertia::scroll()` to configure the paginated data. Use the `search-docs` tool with a query of `infinite scroll` for detailed guidance on buffers, manual loading, reverse mode, and custom trigger elements.\n\n## Server-Side Patterns\n\nServer-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.\n\n## Common Pitfalls\n\n- Using traditional `\u003Ca>` links instead of Inertia's `\u003CLink>` component (breaks SPA behavior)\n- Forgetting to add loading states (skeleton screens) when using deferred props\n- Not handling the `undefined` state of deferred props before data loads\n- Using `\u003Cform>` without preventing default submission (use `\u003CForm>` component or `e.preventDefault()`)\n- Forgetting to check if `\u003CForm>` component is available in your Inertia version\n- Using `router.cancel()` instead of `router.cancelAll()` (v3 breaking change)\n- Using `router.on('invalid', ...)` or `router.on('exception', ...)` instead of the renamed `httpException` and `networkError` events",{"name":5,"license":15,"metadata":48,"description":7},{"author":29},"master","79beae0642932e7449e542b7e907f8283936ebb1",".agents\u002Fskills\u002Finertia-react-development","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI","https:\u002F\u002Fgithub.com\u002Fimbasri","\r\njust a fan of a cat 😸, and a coffee lover☕","2026-04-01 15:02:20",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add imbasri\u002FlaraAI --skill inertia-react-development",{"tool":62,"command":63},"bunx","bunx skills add imbasri\u002FlaraAI --skill inertia-react-development",{"tool":65,"command":66},"pnpm","pnpm dlx skills add imbasri\u002FlaraAI --skill inertia-react-development","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Finertia-react-development\u002FSKILL.md",true,[],[71,96,124,150],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":78,"publishedAt":43},"01M6KB70J2FTRT2V9YYXJ3ND6X","wayfinder-development","Use this skill for Laravel Wayfinder which auto-generates typed functions for Laravel controllers and routes. ALWAYS use this skill when frontend code needs to call backend routes or controller actions. Trigger when: connecting any React\u002FVue\u002FSvelte\u002FInertia frontend to Laravel controllers, routes, building end-to-end features with both frontend and backend, wiring up forms or links to backend endpoints, fixing route-related TypeScript errors, importing from @\u002Factions or @\u002Froutes, or running wayfinder:generate. Use Wayfinder route functions instead of hardcoded URLs. Covers: wayfinder() vite plugin, .url()\u002F.get()\u002F.post()\u002F.form(), query params, route model binding, tree-shaking. Do not use for backend-only task","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Fwayfinder-development\u002FSKILL.md",[77],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[79,80,24,81,82,83,84,85,86,87,29,88,89,90,91,92,93,94,95,26],"wayfinder development","wayfinder","which","wiring","frontend","errors","URL","code","actions","model","auto","only","up","query","get","svelte","end",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":106,"publishedAt":43},"01M6KB6VQJKK5NW620MADC7FW1","tailwindcss-development","Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex\u002Fgrid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3\u002Fv4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML\u002FCSS component, CSS file audits, build tool configuration, and vanilla CSS.","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Ftailwindcss-development\u002FSKILL.md",[102,103],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":104,"categoryName":105,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[107,24,108,109,110,111,34,112,113,114,29,115,116,117,118,119,120,121,122,123],"tailwindcss","tailwindcss development","card","database queries","message","mobile","work","mode","Tailwind","api","database","product","component","writing","utility","css","components",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":133,"publishedAt":43},"01M6KB6PYE5N83TBVPYJ5T1YA6","pest-testing","Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests\u002FFeature, tests\u002FUnit, tests\u002FBrowser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: it()\u002Fexpect() syntax, datasets, mocking, browser testing (visit\u002Fclick\u002Ffill), smoke testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for factories, seeders, migrations, controllers, models, or non-test PHP code.","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Fpest-testing\u002FSKILL.md",[130],{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[134,135,136,137,138,139,140,84,141,142,143,144,145,90,146,29,147,148,149,86],"pest testing","testing","change","workflows","architecture","activate","directories","unit","how to","click","arch","files","livewire","projects","browser testing","browser",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":157,"publishedAt":43},"01M6KB6EH4RJA9FH2ZMCT25Y8W","laravel-best-practices","Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns.","https:\u002F\u002Fgithub.com\u002Fimbasri\u002FlaraAI\u002Fblob\u002Fmaster\u002F.agents\u002Fskills\u002Flaravel-best-practices\u002FSKILL.md",[156],{"categoryNo":104,"categoryName":105,"taxonomyType":21,"taxonomyTypeDesc":22},[158,159,29,160,161,162,163,164,165,166,167,168,92,169,170,171,86,172,173,120],"laravel best practices","best practices","caching","scheduled","reviews","code patterns","security patterns","error","commands","strategies","route","patterns","refactoring","issues","performance","security"]