inertia-react-development
Develops Inertia.js v3 React client-side applications. Activates when creating React pages, forms, or navigation; using <Link>, <Form>, 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.
- License 许可
- MIT
- 所属仓库
- imbasri/laraAI
- 最近更新
- 2026-04-01
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- inertia-react-development
- license
- MIT
- metadata
- { "author": "laravel" }
- description
- Develops Inertia.js v3 React client-side applications. Activates when creating React pages, forms, or navigation; using <Link>, <Form>, 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.
03 SKILL.md 正文
Inertia React Development
When to Apply
Activate this skill when:
- Creating or modifying React page components for Inertia
- Working with forms in React (using
<Form>,useForm, oruseHttp) - Implementing client-side navigation with
<Link>orrouter - Using v3 features: deferred props, prefetching, optimistic updates, instant visits, layout props, HTTP requests, WhenVisible, InfiniteScroll, once props, flash data, or polling
- Building React-specific features with the Inertia protocol
Documentation
Use search-docs for detailed Inertia v3 React patterns and documentation.
Basic Usage
Page Components Location
React page components should be placed in the resources/js/pages directory.
Page Component Structure
<!-- Basic React Page Component -->
export default function UsersIndex({ users }) {
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
</div>
)
}
Client-Side Navigation
Basic Link Component
Use <Link> for client-side navigation instead of traditional <a> tags:
<!-- Inertia React Navigation -->
import { Link, router } from '@inertiajs/react'
<Link href="/">Home</Link>
<Link href="/users">Users</Link>
<Link href={`/users/${user.id}`}>View User</Link>
Link with Method
<!-- Link with POST Method -->
import { Link } from '@inertiajs/react'
<Link href="/logout" method="post" as="button">
Logout
</Link>
Prefetching
Prefetch pages to improve perceived performance:
<!-- Prefetch on Hover -->
import { Link } from '@inertiajs/react'
<Link href="/users" prefetch>
Users
</Link>
Programmatic Navigation
<!-- Router Visit -->
import { router } from '@inertiajs/react'
function handleClick() {
router.visit('/users')
}
// Or with options
router.visit('/users', {
method: 'post',
data: { name: 'John' },
onSuccess: () => console.log('Success!'),
})
Form Handling
Form Component (Recommended)
The recommended way to build forms is with the <Form> component:
<!-- Form Component Example -->
import { Form } from '@inertiajs/react'
export default function CreateUser() {
return (
<Form action="/users" method="post">
{({ errors, processing, wasSuccessful }) => (
<>
<input type="text" name="name" />
{errors.name && <div>{errors.name}</div>}
<input type="email" name="email" />
{errors.email && <div>{errors.email}</div>}
<button type="submit" disabled={processing}>
{processing ? 'Creating...' : 'Create User'}
</button>
{wasSuccessful && <div>User created!</div>}
</>
)}
</Form>
)
}
Form Component With All Props
<!-- Form Component Full Example -->
import { Form } from '@inertiajs/react'
<Form action="/users" method="post">
{({
errors,
hasErrors,
processing,
progress,
wasSuccessful,
recentlySuccessful,
clearErrors,
resetAndClearErrors,
defaults,
isDirty,
reset,
submit
}) => (
<>
<input type="text" name="name" defaultValue={defaults.name} />
{errors.name && <div>{errors.name}</div>}
<button type="submit" disabled={processing}>
{processing ? 'Saving...' : 'Save'}
</button>
{progress && (
<progress value={progress.percentage} max="100">
{progress.percentage}%
</progress>
)}
{wasSuccessful && <div>Saved!</div>}
</>
)}
</Form>
Form Component Reset Props
The <Form> component supports automatic resetting:
resetOnError- Reset form data when the request failsresetOnSuccess- Reset form data when the request succeedssetDefaultsOnSuccess- Update default values on success
Use the search-docs tool with a query of form component resetting for detailed guidance.
<!-- Form with Reset Props -->
import { Form } from '@inertiajs/react'
<Form
action="/users"
method="post"
resetOnSuccess
setDefaultsOnSuccess
>
{({ errors, processing, wasSuccessful }) => (
<>
<input type="text" name="name" />
{errors.name && <div>{errors.name}</div>}
<button type="submit" disabled={processing}>
Submit
</button>
</>
)}
</Form>
Forms 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.
useForm Hook
For more programmatic control or to follow existing conventions, use the useForm hook:
<!-- useForm Hook Example -->
import { useForm } from '@inertiajs/react'
export default function CreateUser() {
const { data, setData, post, processing, errors, reset } = useForm({
name: '',
email: '',
password: '',
})
function submit(e) {
e.preventDefault()
post('/users', {
onSuccess: () => reset('password'),
})
}
return (
<form onSubmit={submit}>
<input
type="text"
value={data.name}
onChange={e => setData('name', e.target.value)}
/>
{errors.name && <div>{errors.name}</div>}
<input
type="email"
value={data.email}
onChange={e => setData('email', e.target.value)}
/>
{errors.email && <div>{errors.email}</div>}
<input
type="password"
value={data.password}
onChange={e => setData('password', e.target.value)}
/>
{errors.password && <div>{errors.password}</div>}
<button type="submit" disabled={processing}>
Create User
</button>
</form>
)
}
Inertia v3 Features
HTTP Requests
Use 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.
<!-- useHttp Example -->
import { useHttp } from '@inertiajs/react'
export default function Search() {
const { data, setData, get, processing } = useHttp({
query: '',
})
function search(e) {
setData('query', e.target.value)
get('/api/search', {
onSuccess: (response) => {
console.log(response)
},
})
}
return (
<>
<input value={data.query} onChange={search} />
{processing && <div>Searching...</div>}
</>
)
}
Optimistic Updates
Apply data changes instantly before the server responds, with automatic rollback on failure:
<!-- Optimistic Update with Router -->
import { router } from '@inertiajs/react'
function like(post) {
router.optimistic((props) => ({
post: {
...props.post,
likes: props.post.likes + 1,
},
})).post(`/posts/${post.id}/like`)
}
Optimistic updates also work with useForm and the <Form> component:
<!-- Optimistic Update with Form Component -->
import { Form } from '@inertiajs/react'
<Form
action="/todos"
method="post"
optimistic={(props, data) => ({
todos: [...props.todos, { id: Date.now(), name: data.name, done: false }],
})}
>
<input type="text" name="name" />
<button type="submit">Add Todo</button>
</Form>
Instant Visits
Navigate 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.
<!-- Instant Visit with Link -->
import { Link } from '@inertiajs/react'
<Link href="/dashboard" component="Dashboard">Dashboard</Link>
<Link
href="/posts/1"
component="Posts/Show"
pageProps={{ post: { id: 1, title: 'My Post' } }}
>
View Post
</Link>
Layout Props
Share dynamic data between pages and persistent layouts:
<!-- Layout Props in Layout -->
export default function Layout({ title = 'My App', showSidebar = true, children }) {
return (
<>
<header>{title}</header>
{showSidebar && <aside>Sidebar</aside>}
<main>{children}</main>
</>
)
}
<!-- Setting Layout Props from Page -->
import { setLayoutProps } from '@inertiajs/react'
export default function Dashboard() {
setLayoutProps({
title: 'Dashboard',
showSidebar: false,
})
return <h1>Dashboard</h1>
}
Deferred Props
Use deferred props to load data after initial page render:
<!-- Deferred Props with Empty State -->
export default function UsersIndex({ users }) {
return (
<div>
<h1>Users</h1>
{!users ? (
<div className="animate-pulse">
<div className="h-4 bg-gray-200 rounded w-3/4 mb-2"></div>
<div className="h-4 bg-gray-200 rounded w-1/2"></div>
</div>
) : (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)}
</div>
)
}
Polling
Use the usePoll hook to automatically refresh data at intervals. It handles cleanup on unmount and throttles polling when the tab is inactive.
<!-- Basic Polling -->
import { usePoll } from '@inertiajs/react'
export default function Dashboard({ stats }) {
usePoll(5000)
return (
<div>
<h1>Dashboard</h1>
<div>Active Users: {stats.activeUsers}</div>
</div>
)
}
<!-- Polling With Request Options and Manual Control -->
import { usePoll } from '@inertiajs/react'
export default function Dashboard({ stats }) {
const { start, stop } = usePoll(5000, {
only: ['stats'],
onStart() {
console.log('Polling request started')
},
onFinish() {
console.log('Polling request finished')
},
}, {
autoStart: false,
keepAlive: true,
})
return (
<div>
<h1>Dashboard</h1>
<div>Active Users: {stats.activeUsers}</div>
<button onClick={start}>Start Polling</button>
<button onClick={stop}>Stop Polling</button>
</div>
)
}
autoStart(defaulttrue) - set tofalseto start polling manually via the returnedstart()functionkeepAlive(defaultfalse) - set totrueto prevent throttling when the browser tab is inactive
WhenVisible
Lazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:
<!-- WhenVisible Example -->
import { WhenVisible } from '@inertiajs/react'
export default function Dashboard({ stats }) {
return (
<div>
<h1>Dashboard</h1>
<WhenVisible data="stats" buffer={200} fallback={<div className="animate-pulse">Loading stats...</div>}>
{({ fetching }) => (
<div>
<p>Total Users: {stats.total_users}</p>
<p>Revenue: {stats.revenue}</p>
{fetching && <span>Refreshing...</span>}
</div>
)}
</WhenVisible>
</div>
)
}
InfiniteScroll
Automatically load additional pages of paginated data as users scroll:
<!-- InfiniteScroll Example -->
import { InfiniteScroll } from '@inertiajs/react'
export default function Users({ users }) {
return (
<InfiniteScroll data="users">
{users.data.map(user => (
<div key={user.id}>{user.name}</div>
))}
</InfiniteScroll>
)
}
The 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.
Server-Side Patterns
Server-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.
Common Pitfalls
- Using traditional
<a>links instead of Inertia's<Link>component (breaks SPA behavior) - Forgetting to add loading states (skeleton screens) when using deferred props
- Not handling the
undefinedstate of deferred props before data loads - Using
<form>without preventing default submission (use<Form>component ore.preventDefault()) - Forgetting to check if
<Form>component is available in your Inertia version - Using
router.cancel()instead ofrouter.cancelAll()(v3 breaking change) - Using
router.on('invalid', ...)orrouter.on('exception', ...)instead of the renamedhttpExceptionandnetworkErrorevents
04 同仓库更多 Skills
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/Vue/Svelte/Inertia 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 @/actions or @/routes, or running wayfinder:generate. Use Wayfinder route functions instead of hardcoded URLs. Covers: wayfinder() vite plugin, .url()/.get()/.post()/.form(), query params, route model binding, tree-shaking. Do not use for backend-only task
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/grid 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/v4 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/CSS component, CSS file audits, build tool configuration, and vanilla CSS.
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/Feature, tests/Unit, tests/Browser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: it()/expect() syntax, datasets, mocking, browser testing (visit/click/fill), 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.
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.