Direct Answer
InertiaJS v1.x has no built-in mechanism to acknowledge flash consumption during partial reloads with preserveState: true. The $page.props.flash object is merged into the existing page state rather than replaced, so messages persist until you clear them client-side or perform a full page visit.
Recommended Pattern: Client-Side Clear in Layout
Consume and clear flash messages immediately after rendering in a shared layout component. This runs on every page update, including partial reloads.
// Vue 3 example using Composition API
import { onMounted, watch } from 'vue'
import { usePage } from '@inertiajs/vue3'
const page = usePage()
function consumeFlash() {
const flash = page.props.flash
if (flash && Object.keys(flash).length) {
// Display toasts/notifications here
Object.entries(flash).forEach(([type, message]) => {
toast[type](message)
})
// Clear reactively
page.props.flash = {}
}
}
// Run on initial mount and after every Inertia visit
onMounted(consumeFlash)
watch(() => page.props.flash, consumeFlash, { deep: true })
Alternative: Clear in Visit Callback
If you only want to clear after a specific action triggers a partial reload:
router.visit(url, {
preserveState: true,
onSuccess: () => {
page.props.flash = {}
}
})
Why Server-Side Sync Isn't Automatic
The server only sends flash data on full visits or when explicitly included in a partial response. It has no way to know the client displayed a message unless the client makes a subsequent request. router.reload({ only: ['flash'] }) would reset server-side flash but adds an unnecessary network round-trip.
Caveats to Verify
- Reactivity: Direct mutation
page.props.flash = {} works with Vue 3's reactive proxy. In React/Svelte, use the framework's state update pattern.
- Race conditions: Rapid successive partial reloads may clear messages before they display. Guard with a flag or queue if needed.
- Version: Confirm your InertiaJS version (
package.json). v2 may change this behavior.
Verification Steps
- Open DevTools Network tab, trigger a partial reload with
preserveState: true, and confirm flash props appear in the XHR response.
- Add
console.log(page.props.flash) before and after your clearing logic to verify it empties.
- Test rapid successive partial reloads to ensure no message reappears unexpectedly.
What InertiaJS version are you using? The exact clearing syntax differs slightly between Vue 2/3, React, and Svelte adapters.