Skip to content

Commit cfb9a8b

Browse files
authored
Merge pull request #14 from inertiajs/flash-data
Docs for `Inertia::flash()`
1 parent 91510a0 commit cfb9a8b

File tree

4 files changed

+319
-77
lines changed

4 files changed

+319
-77
lines changed

docs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"group": "Data & Props",
119119
"pages": [
120120
"v2/data-props/shared-data",
121+
"v2/data-props/flash-data",
121122
"v2/data-props/partial-reloads",
122123
"v2/data-props/deferred-props",
123124
"v2/data-props/merging-props",

v2/advanced/events.mdx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,48 @@ router.on('success', (event) => {
435435

436436
The `success` event is not cancelable.
437437

438+
## Flash
439+
440+
<Badge>v2.3.3+</Badge>
441+
442+
The `flash` event fires when [flash data](/v2/data-props/flash-data) is received from the server. This is useful for displaying toast notifications or handling temporary data in a central location.
443+
444+
<CodeGroup>
445+
446+
```js Vue icon="vuejs"
447+
import { router } from '@inertiajs/vue3'
448+
449+
router.on('flash', (event) => {
450+
if (event.detail.flash.toast) {
451+
showToast(event.detail.flash.toast)
452+
}
453+
})
454+
```
455+
456+
```jsx React icon="react"
457+
import { router } from '@inertiajs/react'
458+
459+
router.on('flash', (event) => {
460+
if (event.detail.flash.toast) {
461+
showToast(event.detail.flash.toast)
462+
}
463+
})
464+
```
465+
466+
```js Svelte icon="s"
467+
import { router } from '@inertiajs/svelte'
468+
469+
router.on('flash', (event) => {
470+
if (event.detail.flash.toast) {
471+
showToast(event.detail.flash.toast)
472+
}
473+
})
474+
```
475+
476+
</CodeGroup>
477+
478+
The `flash` event is not cancelable. [Partial reloads](/v2/data-props/partial-reloads) will only trigger the event if the flash data has changed.
479+
438480
## Error
439481

440482
The `error` event fires when validation errors are present on "successful" page visits.

v2/data-props/flash-data.mdx

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
---
2+
title: Flash Data
3+
---
4+
5+
<Badge>v2.3.3+</Badge>
6+
7+
Sometimes you may wish to send one-time data to your frontend that shouldn't reappear when users navigate through browser history. Unlike regular props, flash data isn't persisted in history state, making it ideal for success messages, newly created IDs, or other temporary values.
8+
9+
## Flashing Data
10+
11+
You may flash data using the `Inertia::flash()` method, passing a key and value or an array of key-value pairs.
12+
13+
```php
14+
public function store(Request $request)
15+
{
16+
$user = User::create($request->validated());
17+
18+
Inertia::flash('message', 'User created successfully!');
19+
20+
// Or flash multiple values at once...
21+
Inertia::flash([
22+
'message' => 'User created!',
23+
'newUserId' => $user->id,
24+
]);
25+
26+
return back();
27+
}
28+
```
29+
30+
Chaining with `back()` is also supported.
31+
32+
```php
33+
return Inertia::flash('newUserId', $user->id)->back();
34+
```
35+
36+
You may also chain `flash()` onto `render()`, or vice versa.
37+
38+
```php
39+
return Inertia::render('Projects/Index', [
40+
'projects' => $projects,
41+
])->flash('highlight', $project->id);
42+
43+
// Or...
44+
45+
return Inertia::flash('highlight', $project->id)
46+
->render('Projects/Index', ['projects' => $projects]);
47+
```
48+
49+
Flash data is scoped to the current request. The middleware automatically persists it to the session when redirecting. After the flash data is sent to the client, it is cleared and will not appear in subsequent requests.
50+
51+
## Accessing Flash Data
52+
53+
Flash data is available on `page.flash`. You may also listen for the global `flash` event or use the `onFlash` callback.
54+
55+
<CodeGroup>
56+
57+
```vue Vue icon="vuejs"
58+
<script setup>
59+
import { usePage } from '@inertiajs/vue3'
60+
61+
const page = usePage()
62+
</script>
63+
64+
<template>
65+
<div v-if="page.flash.toast" class="toast">
66+
{{ page.flash.toast.message }}
67+
</div>
68+
</template>
69+
```
70+
71+
```jsx React icon="react"
72+
import { usePage } from '@inertiajs/react'
73+
74+
export default function Layout({ children }) {
75+
const { flash } = usePage()
76+
77+
return (
78+
<>
79+
{flash.toast && <div className="toast">{flash.toast.message}</div>}
80+
{children}
81+
</>
82+
)
83+
}
84+
```
85+
86+
```svelte Svelte icon="s"
87+
<script>
88+
import { page } from '@inertiajs/svelte'
89+
</script>
90+
91+
{#if $page.flash.toast}
92+
<div class="toast">{$page.flash.toast.message}</div>
93+
{/if}
94+
```
95+
96+
</CodeGroup>
97+
98+
## The onFlash Callback
99+
100+
You may use the `onFlash` callback to handle flash data when making requests.
101+
102+
<CodeGroup>
103+
104+
```js Vue icon="vuejs"
105+
import { router } from '@inertiajs/vue3'
106+
107+
router.post('/users', data, {
108+
onFlash: ({ newUserId }) => {
109+
form.userId = newUserId
110+
},
111+
})
112+
```
113+
114+
```js React icon="react"
115+
import { router } from '@inertiajs/react'
116+
117+
router.post('/users', data, {
118+
onFlash: ({ newUserId }) => {
119+
form.userId = newUserId
120+
},
121+
})
122+
```
123+
124+
```js Svelte icon="s"
125+
import { router } from '@inertiajs/svelte'
126+
127+
router.post('/users', data, {
128+
onFlash: ({ newUserId }) => {
129+
form.userId = newUserId
130+
},
131+
})
132+
```
133+
134+
</CodeGroup>
135+
136+
## Global Flash Event
137+
138+
You may use the global `flash` event to handle flash data in a central location, such as a layout component. For more information on events, see the [events documentation](/v2/advanced/events).
139+
140+
<CodeGroup>
141+
142+
```js Vue icon="vuejs"
143+
import { router } from '@inertiajs/vue3'
144+
145+
router.on('flash', (event) => {
146+
if (event.detail.flash.toast) {
147+
showToast(event.detail.flash.toast)
148+
}
149+
})
150+
```
151+
152+
```js React icon="react"
153+
import { router } from '@inertiajs/react'
154+
155+
router.on('flash', (event) => {
156+
if (event.detail.flash.toast) {
157+
showToast(event.detail.flash.toast)
158+
}
159+
})
160+
```
161+
162+
```js Svelte icon="s"
163+
import { router } from '@inertiajs/svelte'
164+
165+
router.on('flash', (event) => {
166+
if (event.detail.flash.toast) {
167+
showToast(event.detail.flash.toast)
168+
}
169+
})
170+
```
171+
172+
</CodeGroup>
173+
174+
Native browser events are also supported.
175+
176+
<CodeGroup>
177+
178+
```js Vue icon="vuejs"
179+
document.addEventListener('inertia:flash', (event) => {
180+
console.log(event.detail.flash)
181+
})
182+
```
183+
184+
```js React icon="react"
185+
document.addEventListener('inertia:flash', (event) => {
186+
console.log(event.detail.flash)
187+
})
188+
```
189+
190+
```js Svelte icon="s"
191+
document.addEventListener('inertia:flash', (event) => {
192+
console.log(event.detail.flash)
193+
})
194+
```
195+
196+
</CodeGroup>
197+
198+
The `flash` event is not cancelable. During [partial reloads](/v2/data-props/partial-reloads), it only fires if the flash data has changed.
199+
200+
## Client-Side Flash
201+
202+
You may set flash data on the client without a server request using the `router.flash()` method. Values are merged with existing flash data.
203+
204+
<CodeGroup>
205+
206+
```js Vue icon="vuejs"
207+
import { router } from '@inertiajs/vue3'
208+
209+
router.flash('foo', 'bar')
210+
router.flash({ foo: 'bar' })
211+
```
212+
213+
```js React icon="react"
214+
import { router } from '@inertiajs/react'
215+
216+
router.flash('foo', 'bar')
217+
router.flash({ foo: 'bar' })
218+
```
219+
220+
```js Svelte icon="s"
221+
import { router } from '@inertiajs/svelte'
222+
223+
router.flash('foo', 'bar')
224+
router.flash({ foo: 'bar' })
225+
```
226+
227+
</CodeGroup>
228+
229+
A callback may also be passed to access the current flash data or replace it entirely.
230+
231+
<CodeGroup>
232+
233+
```js Vue icon="vuejs"
234+
import { router } from '@inertiajs/vue3'
235+
236+
router.flash((current) => ({ ...current, bar: 'baz' }))
237+
router.flash(() => ({}))
238+
```
239+
240+
```js React icon="react"
241+
import { router } from '@inertiajs/react'
242+
243+
router.flash((current) => ({ ...current, bar: 'baz' }))
244+
router.flash(() => ({}))
245+
```
246+
247+
```js Svelte icon="s"
248+
import { router } from '@inertiajs/svelte'
249+
250+
router.flash((current) => ({ ...current, bar: 'baz' }))
251+
router.flash(() => ({}))
252+
```
253+
254+
</CodeGroup>
255+
256+
## TypeScript
257+
258+
You may configure the flash data type globally using TypeScript's declaration merging.
259+
260+
```ts
261+
// global.d.ts
262+
declare module '@inertiajs/core' {
263+
export interface InertiaConfig {
264+
flashDataType: {
265+
toast?: {
266+
type: 'success' | 'error'
267+
message: string
268+
}
269+
}
270+
}
271+
}
272+
```
273+
274+
With this configuration, `page.flash.toast` will be properly typed as `{ type: "success" | "error"; message: string } | undefined`.

0 commit comments

Comments
 (0)