@inertiajs/react 2.3.16 → 2.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inertiajs/react",
3
- "version": "2.3.16",
3
+ "version": "2.3.17",
4
4
  "license": "MIT",
5
5
  "description": "The React adapter for Inertia.js",
6
6
  "contributors": [
@@ -18,7 +18,8 @@
18
18
  },
19
19
  "files": [
20
20
  "dist",
21
- "types"
21
+ "types",
22
+ "resources"
22
23
  ],
23
24
  "type": "module",
24
25
  "main": "dist/index.js",
@@ -46,7 +47,7 @@
46
47
  "@types/react": "^19.2.14",
47
48
  "@types/react-dom": "^19.2.3",
48
49
  "axios": "^1.13.5",
49
- "es-check": "^9.5.4",
50
+ "es-check": "^9.6.1",
50
51
  "esbuild": "^0.27.3",
51
52
  "esbuild-node-externals": "^1.20.1",
52
53
  "react": "^19.2.4",
@@ -61,7 +62,7 @@
61
62
  "@types/lodash-es": "^4.17.12",
62
63
  "laravel-precognition": "^1.0.2",
63
64
  "lodash-es": "^4.17.23",
64
- "@inertiajs/core": "2.3.16"
65
+ "@inertiajs/core": "2.3.17"
65
66
  },
66
67
  "scripts": {
67
68
  "build": "pnpm clean && ./build.js && tsc",
@@ -0,0 +1,3 @@
1
+ # Inertia + React
2
+
3
+ - IMPORTANT: Activate `inertia-react-development` when working with Inertia React client-side patterns.
@@ -0,0 +1,362 @@
1
+ ---
2
+ name: inertia-react-development
3
+ description: "Develops Inertia.js v2 React client-side applications. Activates when creating React pages, forms, or navigation; using <Link>, <Form>, useForm, or router; working with deferred props, prefetching, or polling; or when user mentions React with Inertia, React pages, React forms, or React navigation."
4
+ license: MIT
5
+ metadata:
6
+ author: laravel
7
+ ---
8
+ @php
9
+ /** @var \Laravel\Boost\Install\GuidelineAssist $assist */
10
+ @endphp
11
+ # Inertia React Development
12
+
13
+ ## When to Apply
14
+
15
+ Activate this skill when:
16
+
17
+ - Creating or modifying React page components for Inertia
18
+ - Working with forms in React (using `<Form>` or `useForm`)
19
+ - Implementing client-side navigation with `<Link>` or `router`
20
+ - Using v2 features: deferred props, prefetching, WhenVisible, InfiniteScroll, once props, flash data, or polling
21
+ - Building React-specific features with the Inertia protocol
22
+
23
+ ## Documentation
24
+
25
+ Use `search-docs` for detailed Inertia v2 React patterns and documentation.
26
+
27
+ ## Basic Usage
28
+
29
+ ### Page Components Location
30
+
31
+ React page components should be placed in the `{{ $assist->inertia()->pagesDirectory() }}` directory.
32
+
33
+ ### Page Component Structure
34
+
35
+ @boostsnippet("Basic React Page Component", "react")
36
+ export default function UsersIndex({ users }) {
37
+ return (
38
+ <div>
39
+ <h1>Users</h1>
40
+ <ul>
41
+ {users.map(user => <li key={user.id}>{user.name}</li>)}
42
+ </ul>
43
+ </div>
44
+ )
45
+ }
46
+ @endboostsnippet
47
+
48
+ ## Client-Side Navigation
49
+
50
+ ### Basic Link Component
51
+
52
+ Use `<Link>` for client-side navigation instead of traditional `<a>` tags:
53
+
54
+ @boostsnippet("Inertia React Navigation", "react")
55
+ import { Link, router } from '@inertiajs/react'
56
+
57
+ <Link href="/">Home</Link>
58
+ <Link href="/users">Users</Link>
59
+ <Link href={`/users/${user.id}`}>View User</Link>
60
+ @endboostsnippet
61
+
62
+ ### Link with Method
63
+
64
+ @boostsnippet("Link with POST Method", "react")
65
+ import { Link } from '@inertiajs/react'
66
+
67
+ <Link href="/logout" method="post" as="button">
68
+ Logout
69
+ </Link>
70
+ @endboostsnippet
71
+
72
+ ### Prefetching
73
+
74
+ Prefetch pages to improve perceived performance:
75
+
76
+ @boostsnippet("Prefetch on Hover", "react")
77
+ import { Link } from '@inertiajs/react'
78
+
79
+ <Link href="/users" prefetch>
80
+ Users
81
+ </Link>
82
+ @endboostsnippet
83
+
84
+ ### Programmatic Navigation
85
+
86
+ @boostsnippet("Router Visit", "react")
87
+ import { router } from '@inertiajs/react'
88
+
89
+ function handleClick() {
90
+ router.visit('/users')
91
+ }
92
+
93
+ // Or with options
94
+ router.visit('/users', {
95
+ method: 'post',
96
+ data: { name: 'John' },
97
+ onSuccess: () => console.log('Success!'),
98
+ })
99
+ @endboostsnippet
100
+
101
+ ## Form Handling
102
+
103
+ @if($assist->inertia()->hasFormComponent())
104
+ ### Form Component (Recommended)
105
+
106
+ The recommended way to build forms is with the `<Form>` component:
107
+
108
+ @boostsnippet("Form Component Example", "react")
109
+ import { Form } from '@inertiajs/react'
110
+
111
+ export default function CreateUser() {
112
+ return (
113
+ <Form action="/users" method="post">
114
+ {({ errors, processing, wasSuccessful }) => (
115
+ <>
116
+ <input type="text" name="name" />
117
+ {errors.name && <div>{errors.name}</div>}
118
+
119
+ <input type="email" name="email" />
120
+ {errors.email && <div>{errors.email}</div>}
121
+
122
+ <button type="submit" disabled={processing}>
123
+ {processing ? 'Creating...' : 'Create User'}
124
+ </button>
125
+
126
+ {wasSuccessful && <div>User created!</div>}
127
+ </>
128
+ )}
129
+ </Form>
130
+ )
131
+ }
132
+ @endboostsnippet
133
+
134
+ ### Form Component With All Props
135
+
136
+ @boostsnippet("Form Component Full Example", "react")
137
+ import { Form } from '@inertiajs/react'
138
+
139
+ <Form action="/users" method="post">
140
+ {({
141
+ errors,
142
+ hasErrors,
143
+ processing,
144
+ progress,
145
+ wasSuccessful,
146
+ recentlySuccessful,
147
+ clearErrors,
148
+ resetAndClearErrors,
149
+ defaults,
150
+ isDirty,
151
+ reset,
152
+ submit
153
+ }) => (
154
+ <>
155
+ <input type="text" name="name" defaultValue={defaults.name} />
156
+ {errors.name && <div>{errors.name}</div>}
157
+
158
+ <button type="submit" disabled={processing}>
159
+ {processing ? 'Saving...' : 'Save'}
160
+ </button>
161
+
162
+ {progress && (
163
+ <progress value={progress.percentage} max="100">
164
+ {progress.percentage}%
165
+ </progress>
166
+ )}
167
+
168
+ {wasSuccessful && <div>Saved!</div>}
169
+ </>
170
+ )}
171
+ </Form>
172
+ @endboostsnippet
173
+
174
+ @if($assist->inertia()->hasFormComponentResets())
175
+ ### Form Component Reset Props
176
+
177
+ The `<Form>` component supports automatic resetting:
178
+
179
+ - `resetOnError` - Reset form data when the request fails
180
+ - `resetOnSuccess` - Reset form data when the request succeeds
181
+ - `setDefaultsOnSuccess` - Update default values on success
182
+
183
+ Use the `search-docs` tool with a query of `form component resetting` for detailed guidance.
184
+
185
+ @boostsnippet("Form with Reset Props", "react")
186
+ import { Form } from '@inertiajs/react'
187
+
188
+ <Form
189
+ action="/users"
190
+ method="post"
191
+ resetOnSuccess
192
+ setDefaultsOnSuccess
193
+ >
194
+ {({ errors, processing, wasSuccessful }) => (
195
+ <>
196
+ <input type="text" name="name" />
197
+ {errors.name && <div>{errors.name}</div>}
198
+
199
+ <button type="submit" disabled={processing}>
200
+ Submit
201
+ </button>
202
+ </>
203
+ )}
204
+ </Form>
205
+ @endboostsnippet
206
+ @else
207
+ Note: This version of Inertia does not support `resetOnError`, `resetOnSuccess`, or `setDefaultsOnSuccess` on the `<Form>` component. Using these props will cause errors. Upgrade to Inertia v2.2.0+ to use these features.
208
+ @endif
209
+
210
+ 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.
211
+
212
+ @endif
213
+
214
+ ### `useForm` Hook
215
+
216
+ @if($assist->inertia()->hasFormComponent() === false)
217
+ For Inertia v2.0.x: Build forms using the `useForm` helper as the `<Form>` component is not available until v2.1.0+.
218
+ @else
219
+ For more programmatic control or to follow existing conventions, use the `useForm` hook:
220
+ @endif
221
+
222
+ @boostsnippet("useForm Hook Example", "react")
223
+ import { useForm } from '@inertiajs/react'
224
+
225
+ export default function CreateUser() {
226
+ const { data, setData, post, processing, errors, reset } = useForm({
227
+ name: '',
228
+ email: '',
229
+ password: '',
230
+ })
231
+
232
+ function submit(e) {
233
+ e.preventDefault()
234
+ post('/users', {
235
+ onSuccess: () => reset('password'),
236
+ })
237
+ }
238
+
239
+ return (
240
+ <form onSubmit={submit}>
241
+ <input
242
+ type="text"
243
+ value={data.name}
244
+ onChange={e => setData('name', e.target.value)}
245
+ />
246
+ {errors.name && <div>{errors.name}</div>}
247
+
248
+ <input
249
+ type="email"
250
+ value={data.email}
251
+ onChange={e => setData('email', e.target.value)}
252
+ />
253
+ {errors.email && <div>{errors.email}</div>}
254
+
255
+ <input
256
+ type="password"
257
+ value={data.password}
258
+ onChange={e => setData('password', e.target.value)}
259
+ />
260
+ {errors.password && <div>{errors.password}</div>}
261
+
262
+ <button type="submit" disabled={processing}>
263
+ Create User
264
+ </button>
265
+ </form>
266
+ )
267
+ }
268
+ @endboostsnippet
269
+
270
+ ## Inertia v2 Features
271
+
272
+ ### Deferred Props
273
+
274
+ Use deferred props to load data after initial page render:
275
+
276
+ @boostsnippet("Deferred Props with Empty State", "react")
277
+ export default function UsersIndex({ users }) {
278
+ // users will be undefined initially, then populated
279
+ return (
280
+ <div>
281
+ <h1>Users</h1>
282
+ {!users ? (
283
+ <div className="animate-pulse">
284
+ <div className="h-4 bg-gray-200 rounded w-3/4 mb-2"></div>
285
+ <div className="h-4 bg-gray-200 rounded w-1/2"></div>
286
+ </div>
287
+ ) : (
288
+ <ul>
289
+ {users.map(user => (
290
+ <li key={user.id}>{user.name}</li>
291
+ ))}
292
+ </ul>
293
+ )}
294
+ </div>
295
+ )
296
+ }
297
+ @endboostsnippet
298
+
299
+ ### Polling
300
+
301
+ Automatically refresh data at intervals:
302
+
303
+ @boostsnippet("Polling Example", "react")
304
+ import { router } from '@inertiajs/react'
305
+ import { useEffect } from 'react'
306
+
307
+ export default function Dashboard({ stats }) {
308
+ useEffect(() => {
309
+ const interval = setInterval(() => {
310
+ router.reload({ only: ['stats'] })
311
+ }, 5000) // Poll every 5 seconds
312
+
313
+ return () => clearInterval(interval)
314
+ }, [])
315
+
316
+ return (
317
+ <div>
318
+ <h1>Dashboard</h1>
319
+ <div>Active Users: {stats.activeUsers}</div>
320
+ </div>
321
+ )
322
+ }
323
+ @endboostsnippet
324
+
325
+ ### WhenVisible
326
+
327
+ Lazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:
328
+
329
+ @boostsnippet("WhenVisible Example", "react")
330
+ import { WhenVisible } from '@inertiajs/react'
331
+
332
+ export default function Dashboard({ stats }) {
333
+ return (
334
+ <div>
335
+ <h1>Dashboard</h1>
336
+
337
+ {/* stats prop is loaded only when this section scrolls into view */}
338
+ <WhenVisible data="stats" buffer={200} fallback={<div className="animate-pulse">Loading stats...</div>}>
339
+ {({ fetching }) => (
340
+ <div>
341
+ <p>Total Users: {stats.total_users}</p>
342
+ <p>Revenue: {stats.revenue}</p>
343
+ {fetching && <span>Refreshing...</span>}
344
+ </div>
345
+ )}
346
+ </WhenVisible>
347
+ </div>
348
+ )
349
+ }
350
+ @endboostsnippet
351
+
352
+ ## Server-Side Patterns
353
+
354
+ Server-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.
355
+
356
+ ## Common Pitfalls
357
+
358
+ - Using traditional `<a>` links instead of Inertia's `<Link>` component (breaks SPA behavior)
359
+ - Forgetting to add loading states (skeleton screens) when using deferred props
360
+ - Not handling the `undefined` state of deferred props before data loads
361
+ - Using `<form>` without preventing default submission (use `<Form>` component or `e.preventDefault()`)
362
+ - Forgetting to check if `<Form>` component is available in your Inertia version