Skip to content

Commit 2283f20

Browse files
committed
Add flash data docs
1 parent 0d4a9ff commit 2283f20

File tree

4 files changed

+345
-78
lines changed

4 files changed

+345
-78
lines changed

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export default defineConfig({
130130
text: 'Data & Props',
131131
items: [
132132
{ text: 'Shared data', link: '/guide/shared-data' },
133+
{ text: 'Flash data', link: '/guide/flash-data' },
133134
{ text: 'Partial reloads', link: '/guide/partial-reloads' },
134135
{ text: 'Deferred props', link: '/guide/deferred-props' },
135136
{ text: 'Polling', link: '/guide/polling' },

docs/guide/events.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,53 @@ router.on('success', (event) => {
495495

496496
The `success` event is not cancelable.
497497

498+
## Flash
499+
500+
@available_since rails=master core=2.3.3
501+
502+
The `flash` event fires when [flash data](/guide/flash-data) is received from the server. This is useful for displaying toast notifications or handling temporary data in a central location.
503+
504+
:::tabs key:frameworks
505+
== Vue
506+
507+
```js
508+
import { router } from '@inertiajs/vue3'
509+
510+
router.on('flash', (event) => {
511+
if (event.detail.flash.toast) {
512+
showToast(event.detail.flash.toast)
513+
}
514+
})
515+
```
516+
517+
== React
518+
519+
```js
520+
import { router } from '@inertiajs/react'
521+
522+
router.on('flash', (event) => {
523+
if (event.detail.flash.toast) {
524+
showToast(event.detail.flash.toast)
525+
}
526+
})
527+
```
528+
529+
== Svelte 4|Svelte 5
530+
531+
```js
532+
import { router } from '@inertiajs/svelte'
533+
534+
router.on('flash', (event) => {
535+
if (event.detail.flash.toast) {
536+
showToast(event.detail.flash.toast)
537+
}
538+
})
539+
```
540+
541+
:::
542+
543+
The `flash` event is not cancelable. [Partial reloads](/guide/partial-reloads) will only trigger the event if the flash data has changed.
544+
498545
## Error
499546

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

docs/guide/flash-data.md

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# Flash Data
2+
3+
@available_since rails=master core=2.3.3
4+
5+
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.
6+
7+
## Flashing Data
8+
9+
You may flash data using the `inertia_flash` controller method.
10+
11+
```ruby
12+
class UsersController < ApplicationController
13+
def edit
14+
user = User.new(user_params)
15+
16+
if user.save
17+
inertia_flash[:message] = 'User created successfully!'
18+
19+
redirect_to users_url
20+
else
21+
redirect_to new_user_url, inertia: { errors: user.errors }
22+
end
23+
end
24+
end
25+
```
26+
27+
Passing props to `redirect_to` is also supported.
28+
29+
```ruby
30+
redirect_to users_url, inertia: { flash: { new_user_id: user.id } }
31+
```
32+
33+
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.
34+
35+
## Accessing Flash Data
36+
37+
Flash data is available on `page.flash`. You may also listen for the global `flash` event or use the `onFlash` callback.
38+
39+
:::tabs key:frameworks
40+
41+
== Vue
42+
43+
```vue
44+
<script setup>
45+
import { usePage } from '@inertiajs/vue3'
46+
47+
const page = usePage()
48+
</script>
49+
50+
<template>
51+
<div v-if="page.flash.toast" class="toast">
52+
{{ page.flash.toast.message }}
53+
</div>
54+
</template>
55+
```
56+
57+
== React
58+
59+
```jsx
60+
import { usePage } from '@inertiajs/react'
61+
62+
export default function Layout({ children }) {
63+
const { flash } = usePage()
64+
65+
return (
66+
<>
67+
{flash.toast && <div className="toast">{flash.toast.message}</div>}
68+
{children}
69+
</>
70+
)
71+
}
72+
```
73+
74+
== Svelte 4|Svelte 5
75+
76+
```svelte
77+
<script>
78+
import { page } from '@inertiajs/svelte'
79+
</script>
80+
81+
{#if $page.flash.toast}
82+
<div class="toast">{$page.flash.toast.message}</div>
83+
{/if}
84+
```
85+
86+
:::
87+
88+
## The onFlash Callback
89+
90+
You may use the `onFlash` callback to handle flash data when making requests.
91+
92+
:::tabs key:frameworks
93+
94+
== Vue
95+
96+
```js
97+
import { router } from '@inertiajs/vue3'
98+
99+
router.post('/users', data, {
100+
onFlash: ({ newUserId }) => {
101+
form.userId = newUserId
102+
},
103+
})
104+
```
105+
106+
== React
107+
108+
```js
109+
import { router } from '@inertiajs/react'
110+
111+
router.post('/users', data, {
112+
onFlash: ({ newUserId }) => {
113+
form.userId = newUserId
114+
},
115+
})
116+
```
117+
118+
== Svelte
119+
120+
```js
121+
import { router } from '@inertiajs/svelte'
122+
123+
router.post('/users', data, {
124+
onFlash: ({ newUserId }) => {
125+
form.userId = newUserId
126+
},
127+
})
128+
```
129+
130+
:::
131+
132+
## Global Flash Event
133+
134+
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).
135+
136+
:::tabs key:frameworks
137+
138+
== Vue
139+
140+
```js
141+
import { router } from '@inertiajs/vue3'
142+
143+
router.on('flash', (event) => {
144+
if (event.detail.flash.toast) {
145+
showToast(event.detail.flash.toast)
146+
}
147+
})
148+
```
149+
150+
== React
151+
152+
```js
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+
== Svelte 4|Svelte 5
163+
164+
```js
165+
import { router } from '@inertiajs/svelte'
166+
167+
router.on('flash', (event) => {
168+
if (event.detail.flash.toast) {
169+
showToast(event.detail.flash.toast)
170+
}
171+
})
172+
```
173+
174+
:::
175+
176+
Native browser events are also supported.
177+
178+
:::tabs key:frameworks
179+
180+
== Vue
181+
182+
```js Vue icon="vuejs"
183+
document.addEventListener('inertia:flash', (event) => {
184+
console.log(event.detail.flash)
185+
})
186+
```
187+
188+
== React
189+
190+
```js
191+
document.addEventListener('inertia:flash', (event) => {
192+
console.log(event.detail.flash)
193+
})
194+
```
195+
196+
== Svelte 4|Svelte 5
197+
198+
```js
199+
document.addEventListener('inertia:flash', (event) => {
200+
console.log(event.detail.flash)
201+
})
202+
```
203+
204+
:::
205+
206+
The `flash` event is not cancelable. During [partial reloads](/guide/partial-reloads), it only fires if the flash data has changed.
207+
208+
## Client-Side Flash
209+
210+
You may set flash data on the client without a server request using the `router.flash()` method. Values are merged with existing flash data.
211+
212+
:::tabs key:frameworks
213+
214+
== Vue
215+
216+
```js
217+
import { router } from '@inertiajs/vue3'
218+
219+
router.flash('foo', 'bar')
220+
router.flash({ foo: 'bar' })
221+
```
222+
223+
== React
224+
225+
```js
226+
import { router } from '@inertiajs/react'
227+
228+
router.flash('foo', 'bar')
229+
router.flash({ foo: 'bar' })
230+
```
231+
232+
== Svelte 4|Svelte 5
233+
234+
```js
235+
import { router } from '@inertiajs/svelte'
236+
237+
router.flash('foo', 'bar')
238+
router.flash({ foo: 'bar' })
239+
```
240+
241+
:::
242+
243+
A callback may also be passed to access the current flash data or replace it entirely.
244+
245+
:::tabs key:frameworks
246+
247+
== Vue
248+
249+
```js
250+
import { router } from '@inertiajs/vue3'
251+
252+
router.flash((current) => ({ ...current, bar: 'baz' }))
253+
router.flash(() => ({}))
254+
```
255+
256+
== React
257+
258+
```js
259+
import { router } from '@inertiajs/react'
260+
261+
router.flash((current) => ({ ...current, bar: 'baz' }))
262+
router.flash(() => ({}))
263+
```
264+
265+
== Svelte 4|Svelte 5
266+
267+
```js
268+
import { router } from '@inertiajs/svelte'
269+
270+
router.flash((current) => ({ ...current, bar: 'baz' }))
271+
router.flash(() => ({}))
272+
```
273+
274+
:::
275+
276+
## TypeScript
277+
278+
You may configure the flash data type globally using TypeScript's declaration merging.
279+
280+
```ts
281+
// global.d.ts
282+
declare module '@inertiajs/core' {
283+
export interface InertiaConfig {
284+
flashDataType: {
285+
toast?: {
286+
type: 'success' | 'error'
287+
message: string
288+
}
289+
}
290+
}
291+
}
292+
```
293+
294+
With this configuration, `page.flash.toast` will be properly typed as `{ type: "success" | "error"; message: string } | undefined`.

0 commit comments

Comments
 (0)