From ef2e2d20d7c23b3bba0fa428dd50e6479d553926 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 9 Dec 2025 15:02:39 +0100 Subject: [PATCH 1/5] Flash data --- v2/data-props/flash-data.mdx | 231 ++++++++++++++++++++++++++++++++++ v2/data-props/shared-data.mdx | 79 +----------- 2 files changed, 233 insertions(+), 77 deletions(-) create mode 100644 v2/data-props/flash-data.mdx diff --git a/v2/data-props/flash-data.mdx b/v2/data-props/flash-data.mdx new file mode 100644 index 0000000..59292ac --- /dev/null +++ b/v2/data-props/flash-data.mdx @@ -0,0 +1,231 @@ +--- +title: Flash Data +--- + +Flash data lets you send one-time data to the frontend. Unlike regular props, flash data isn't persisted in browser history state, so it won't reappear when navigating through history. + +## Flashing Data + +You may flash data using the `Inertia::flash()` method. + +```php +public function store(Request $request) +{ + $user = User::create($request->validated()); + + Inertia::flash('toast', [ + 'type' => 'success', + 'message' => 'User created successfully!', + ]); + + return back(); +} +``` + +You may chain `back()` directly onto the `flash()` call. + +```php +return Inertia::flash('newUserId', $user->id)->back(); +``` + +You may also chain `flash()` onto `render()`, or vice versa. + +```php +return Inertia::render('Projects/Index', [ + 'projects' => $projects, +])->flash('highlight', $project->id); + +// Or... + +return Inertia::flash('highlight', $project->id) + ->render('Projects/Index', ['projects' => $projects]); +``` + +Flash data is scoped to the current request. When redirecting, the middleware automatically persists it to the session. + +## Accessing Flash Data + +Flash data is available on `page.flash`. You may also listen for the global `flash` event or use the `onFlash` callback. + + + +```vue Vue icon="vuejs" + + + +``` + +```jsx React icon="react" +import { usePage } from "@inertiajs/react"; + +export default function Layout({ children }) { + const { flash } = usePage(); + + return ( + <> + {flash?.toast &&
{flash.toast.message}
} + {children} + + ); +} +``` + +```svelte Svelte icon="s" + + +{#if $page.flash?.toast} +
{$page.flash.toast.message}
+{/if} +``` + +
+ +## The onFlash Callback + +You may use the `onFlash` callback to handle flash data when making visits. + + + +```js Vue icon="vuejs" +import { router } from "@inertiajs/vue3"; + +router.post("/users", data, { + onFlash: ({ newUserId }) => { + form.userId = newUserId; + }, +}); +``` + +```js React icon="react" +import { router } from "@inertiajs/react"; + +router.post("/users", data, { + onFlash: ({ newUserId }) => { + form.userId = newUserId; + }, +}); +``` + +```js Svelte icon="s" +import { router } from "@inertiajs/svelte"; + +router.post("/users", data, { + onFlash: ({ newUserId }) => { + form.userId = newUserId; + }, +}); +``` + + + +## Global Flash Event + +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). + + + +```js Vue icon="vuejs" +import { router } from "@inertiajs/vue3"; + +router.on("flash", (event) => { + if (event.detail.flash.toast) { + showToast(event.detail.flash.toast); + } +}); +``` + +```js React icon="react" +import { router } from "@inertiajs/react"; + +router.on("flash", (event) => { + if (event.detail.flash.toast) { + showToast(event.detail.flash.toast); + } +}); +``` + +```js Svelte icon="s" +import { router } from "@inertiajs/svelte"; + +router.on("flash", (event) => { + if (event.detail.flash.toast) { + showToast(event.detail.flash.toast); + } +}); +``` + + + +You may also use native browser events. + + + +```js Vue icon="vuejs" +document.addEventListener("inertia:flash", (event) => { + console.log(event.detail.flash); +}); +``` + +```js React icon="react" +document.addEventListener("inertia:flash", (event) => { + console.log(event.detail.flash); +}); +``` + +```js Svelte icon="s" +document.addEventListener("inertia:flash", (event) => { + console.log(event.detail.flash); +}); +``` + + + +The `flash` event is not cancelable. + +## Client-Side Flash + +You may set flash data on the client without a server request using the `router.flash()` method. + + + +```js Vue icon="vuejs" +import { router } from "@inertiajs/vue3"; + +router.flash("foo", "bar"); +router.flash({ foo: "bar" }); + +// Use existing flash data... +router.flash((current) => ({ ...current, bar: "baz" })); +``` + +```js React icon="react" +import { router } from "@inertiajs/react"; + +router.flash("foo", "bar"); +router.flash({ foo: "bar" }); + +// Use existing flash data... +router.flash((current) => ({ ...current, bar: "baz" })); +``` + +```js Svelte icon="s" +import { router } from "@inertiajs/svelte"; + +router.flash("foo", "bar"); +router.flash({ foo: "bar" }); + +// Use existing flash data... +router.flash((current) => ({ ...current, bar: "baz" })); +``` + + diff --git a/v2/data-props/shared-data.mdx b/v2/data-props/shared-data.mdx index c8f9b41..61d151c 100644 --- a/v2/data-props/shared-data.mdx +++ b/v2/data-props/shared-data.mdx @@ -147,81 +147,6 @@ export default function Layout({ children }) { -## Flash Messages +## Flash Data -Another great use-case for shared data is flash messages. These are messages stored in the session only for the next request. For example, it's common to set a flash message after completing a task and before redirecting to a different page. - -Here's a simple way to implement flash messages in your Inertia applications. First, share the flash message on each request. - -```php -class HandleInertiaRequests extends Middleware -{ - public function share(Request $request) - { - return array_merge(parent::share($request), [ - 'flash' => [ - 'message' => fn () => $request->session()->get('message') - ], - ]); - } -} -``` - -Next, display the flash message in a frontend component, such as the site layout. - - - -```vue Vue icon="vuejs" - -``` - -```jsx React icon="react" -import { usePage } from '@inertiajs/react' - -export default function Layout({ children }) { - const { flash } = usePage().props - - return ( -
-
-
- {flash.message && ( -
{flash.message}
- )} - {children} -
-
-
- ) -} -``` - -```svelte Svelte icon="s" - - -
-
-
- {#if $page.props.flash.message} -
{$page.props.flash.message}
- {/if} - -
-
-
-``` - -
+For one-time notifications like toast messages or success alerts, you may use [flash data](/v2/data-props/flash-data). Unlike shared data, flash data is not persisted in the browser's history state, so it won't reappear when navigating through history. From c63bed6a9a51a9e14e091da57b6b38983ec833ed Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Tue, 9 Dec 2025 15:22:39 +0100 Subject: [PATCH 2/5] Update docs.json --- docs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs.json b/docs.json index 16c0f2a..b81e6d5 100644 --- a/docs.json +++ b/docs.json @@ -118,6 +118,7 @@ "group": "Data & Props", "pages": [ "v2/data-props/shared-data", + "v2/data-props/flash-data", "v2/data-props/partial-reloads", "v2/data-props/deferred-props", "v2/data-props/merging-props", From afc793b408523cc382d31b23e07a8cbbf15a1082 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Fri, 12 Dec 2025 16:45:22 +0100 Subject: [PATCH 3/5] Update flash-data.mdx --- v2/data-props/flash-data.mdx | 50 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/v2/data-props/flash-data.mdx b/v2/data-props/flash-data.mdx index 59292ac..44cef99 100644 --- a/v2/data-props/flash-data.mdx +++ b/v2/data-props/flash-data.mdx @@ -51,30 +51,30 @@ Flash data is available on `page.flash`. You may also listen for the global `fla ```vue Vue icon="vuejs" ``` ```jsx React icon="react" -import { usePage } from "@inertiajs/react"; +import { usePage } from '@inertiajs/react' export default function Layout({ children }) { - const { flash } = usePage(); - - return ( - <> - {flash?.toast &&
{flash.toast.message}
} - {children} - - ); + const { flash } = usePage() + + return ( + <> + {flash.toast &&
{flash.toast.message}
} + {children} + + ) } ``` @@ -83,7 +83,7 @@ export default function Layout({ children }) { import { page } from '@inertiajs/svelte' -{#if $page.flash?.toast} +{#if $page.flash.toast}
{$page.flash.toast.message}
{/if} ``` @@ -229,3 +229,23 @@ router.flash((current) => ({ ...current, bar: "baz" })); ``` + +## TypeScript + +You may configure the flash data type globally using TypeScript's declaration merging. This provides type safety when accessing flash data throughout your application. + +```ts +// global.d.ts +declare module "@inertiajs/core" { + export interface InertiaConfig { + flashDataType: { + toast?: { + type: "success" | "error" | "info"; + message: string; + }; + }; + } +} +``` + +With this configuration, `page.flash.toast` will be properly typed as `{ type: "success" | "error" | "info"; message: string } | undefined`. From a9da5dd5bb66764a2b7aee1087842cfbcf36b7d6 Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Fri, 12 Dec 2025 21:16:39 +0100 Subject: [PATCH 4/5] Update flash-data.mdx --- v2/data-props/flash-data.mdx | 49 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/v2/data-props/flash-data.mdx b/v2/data-props/flash-data.mdx index 44cef99..47f0b0e 100644 --- a/v2/data-props/flash-data.mdx +++ b/v2/data-props/flash-data.mdx @@ -6,16 +6,19 @@ Flash data lets you send one-time data to the frontend. Unlike regular props, fl ## Flashing Data -You may flash data using the `Inertia::flash()` method. +You may flash data using the `Inertia::flash()` method, passing a key and value or an array of key-value pairs. ```php public function store(Request $request) { $user = User::create($request->validated()); - Inertia::flash('toast', [ - 'type' => 'success', - 'message' => 'User created successfully!', + Inertia::flash('message', 'User created successfully!'); + + // Or flash multiple values at once... + Inertia::flash([ + 'message' => 'User created!', + 'newUserId' => $user->id, ]); return back(); @@ -41,7 +44,7 @@ return Inertia::flash('highlight', $project->id) ->render('Projects/Index', ['projects' => $projects]); ``` -Flash data is scoped to the current request. When redirecting, the middleware automatically persists it to the session. +Flash data is scoped to the current request. When redirecting, the middleware automatically persists it to the session. After the flash data is sent to the client, it is cleared and will not appear in subsequent requests. ## Accessing Flash Data @@ -194,7 +197,7 @@ The `flash` event is not cancelable. ## Client-Side Flash -You may set flash data on the client without a server request using the `router.flash()` method. +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,9 +206,6 @@ import { router } from "@inertiajs/vue3"; router.flash("foo", "bar"); router.flash({ foo: "bar" }); - -// Use existing flash data... -router.flash((current) => ({ ...current, bar: "baz" })); ``` ```js React icon="react" @@ -213,9 +213,6 @@ import { router } from "@inertiajs/react"; router.flash("foo", "bar"); router.flash({ foo: "bar" }); - -// Use existing flash data... -router.flash((current) => ({ ...current, bar: "baz" })); ``` ```js Svelte icon="s" @@ -223,16 +220,40 @@ import { router } from "@inertiajs/svelte"; router.flash("foo", "bar"); router.flash({ foo: "bar" }); +``` + + + +You may also pass a callback to access the current flash data or replace it entirely. + + + +```js Vue icon="vuejs" +import { router } from "@inertiajs/vue3"; + +router.flash((current) => ({ ...current, bar: "baz" })); +router.flash(() => ({})); +``` + +```js React icon="react" +import { router } from "@inertiajs/react"; + +router.flash((current) => ({ ...current, bar: "baz" })); +router.flash(() => ({})); +``` + +```js Svelte icon="s" +import { router } from "@inertiajs/svelte"; -// Use existing flash data... router.flash((current) => ({ ...current, bar: "baz" })); +router.flash(() => ({})); ``` ## TypeScript -You may configure the flash data type globally using TypeScript's declaration merging. This provides type safety when accessing flash data throughout your application. +You may configure the flash data type globally using TypeScript's declaration merging. ```ts // global.d.ts From b02b02929e3678c9894f73ecff4af1d4917e47ae Mon Sep 17 00:00:00 2001 From: Pascal Baljet Date: Fri, 12 Dec 2025 21:26:17 +0100 Subject: [PATCH 5/5] Update flash-data.mdx --- v2/data-props/flash-data.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/v2/data-props/flash-data.mdx b/v2/data-props/flash-data.mdx index 47f0b0e..aab1475 100644 --- a/v2/data-props/flash-data.mdx +++ b/v2/data-props/flash-data.mdx @@ -25,7 +25,7 @@ public function store(Request $request) } ``` -You may chain `back()` directly onto the `flash()` call. +Chaining with `back()` is also supported. ```php return Inertia::flash('newUserId', $user->id)->back(); @@ -169,7 +169,7 @@ router.on("flash", (event) => { -You may also use native browser events. +Native browser events are also supported. @@ -224,7 +224,7 @@ router.flash({ foo: "bar" }); -You may also pass a callback to access the current flash data or replace it entirely. +A callback may also be passed to access the current flash data or replace it entirely.