npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

inertia-flash-vue

v0.1.1

Published

Vue 3 flash message component for joshdonnell/inertia-flash

Readme

Inertia Flash Vue

Vue 3 adapter for joshdonnell/inertia-flash.

npm version

This package renders the flash messages sent by the Laravel backend. All message configuration — type, duration, dismissibility, title, and metadata — is controlled server-side via the Laravel package. This adapter handles how those messages look and behave in the browser.

Requirements

Installation

npm install inertia-flash-vue

Import the styles and add the component to your app layout:

<script setup>
import { FlashMessages } from 'inertia-flash-vue';
import 'inertia-flash-vue/style.css';
</script>

<template>
    <!-- Your app layout -->
    <FlashMessages />
</template>

That's it. Messages created on the server will appear automatically:

// In your Laravel controller
Flash::success('Profile updated.');
Flash::error('Something went wrong.')->title('Error')->duration(0);

How it works

The Laravel package shares flash data with Inertia on every response:

// Server sends via Inertia::flash()
{
  "messages": [
    {
      "id": "550e8400-...",
      "type": "success",
      "message": "Profile updated.",
      "title": null,
      "duration": 5000,
      "dismissible": true,
      "meta": {}
    }
  ]
}

This adapter watches page.props.flash.messages and renders each message as a toast. The server controls what gets shown (message content, type, duration, dismissibility). The Vue adapter controls how it looks (position, styling, icons, animations).

What the Laravel config controls

These are set in your Laravel config/inertia-flash.php and apply to every message by default:

  • default_duration — auto-dismiss time in milliseconds (0 = persistent)
  • dismissible — whether messages show a close button
  • max_visible — maximum concurrent toasts
  • position — default position on screen

Individual messages can override duration and dismissibility via the fluent API:

Flash::success('Saved!')->duration(8000)->dismissible(false);

What the Vue adapter controls

  • Visual appearance of toasts (colours, spacing, shadows, borders)
  • Icon rendering
  • Progress bar display
  • Transition animations
  • Position on screen (can override the server default)

Props

| Prop | Type | Default | Description | | ------------ | --------------- | ------------- | -------------------------------------------------------------- | | position | FlashPosition | 'top-right' | Where toasts appear on screen | | maxVisible | number | 5 | Maximum toasts visible at once | | icons | boolean | true | Show/hide Lucide icons | | progress | boolean | true | Show auto-dismiss countdown bar | | transition | string | 'flash' | Vue TransitionGroup name | | ui | FlashUI | {} | Tailwind class overrides (see Customisation) |

Position

'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'
<FlashMessages position="bottom-right" />

Customisation

Every element of the toast is styled with Tailwind CSS classes and can be overridden via the ui prop. You only need to pass the classes you want to change — they are intelligently merged with the defaults using tailwind-merge, so rounded-none will properly replace the default rounded-xl.

Using Tailwind CSS v4? If you're using custom classes in the ui prop (e.g. dark mode variants, custom colours), add a @source directive to your app's CSS so Tailwind compiles them:

@source "../node_modules/inertia-flash-vue/dist/**/*.js";

This is only needed if you pass custom Tailwind classes via the ui prop. The built-in default styles work without it.

The ui prop

<FlashMessages
    :ui="{
        container: {
            base: '...', // Outer fixed container
            list: '...', // Inner list wrapper (controls toast width)
        },
        toast: {
            base: '...', // Applied to every toast
            success: '...', // Applied only to success toasts
            error: '...', // Applied only to error toasts
            warning: '...', // Applied only to warning toasts
            info: '...', // Applied only to info toasts
            icon: {
                base: '...', // Icon badge (all types)
                success: '...', // Icon badge (success only)
                error: '...',
                warning: '...',
                info: '...',
            },
            content: '...', // Text content wrapper
            title: '...', // Title text
            message: '...', // Message text
            close: '...', // Dismiss button
            progress: {
                base: '...', // Progress bar (all types)
                success: '...', // Progress bar (success only)
                error: '...',
                warning: '...',
                info: '...',
            },
        },
    }"
/>

Examples

Dark theme:

<FlashMessages
    :ui="{
        toast: {
            base: 'bg-gray-900 border-gray-800 text-gray-100 shadow-2xl',
            success: 'border-l-4 border-l-green-500',
            error: 'border-l-4 border-l-red-500',
            warning: 'border-l-4 border-l-amber-500',
            info: 'border-l-4 border-l-blue-500',
            icon: {
                success: 'bg-green-900 text-green-400',
                error: 'bg-red-900 text-red-400',
                warning: 'bg-amber-900 text-amber-400',
                info: 'bg-blue-900 text-blue-400',
            },
            message: 'text-gray-400',
        },
    }"
/>

Minimal / flat:

<FlashMessages
    :ui="{
        toast: {
            base: 'rounded-none shadow-none border',
            icon: { base: 'rounded-none' },
        },
    }"
/>

Wider toasts:

<FlashMessages
    :ui="{
        container: { list: 'w-[480px]' },
    }"
/>

Default classes

The full default theme is exported as defaultUI if you want to inspect or extend it:

import { defaultUI } from 'inertia-flash-vue';

console.log(defaultUI.toast.success);
// → 'bg-green-50 border-green-200 text-green-900'

Slots

For full control beyond class overrides, the component exposes two scoped slots.

#toast

Replace the entire toast rendering:

<FlashMessages>
  <template #toast="{ message, dismiss }">
    <div class="my-custom-toast">
      {{ message.message }}
      <button @click="dismiss(message.id)">Close</button>
    </div>
  </template>
</FlashMessages>

#icon

Replace just the icon. By default the adapter uses Lucide icons — use this slot to swap in your own icon set:

<FlashMessages>
  <template #icon="{ type, message }">
    <MyCustomIcon :name="type" />
  </template>
</FlashMessages>

To hide icons entirely:

<FlashMessages :icons="false" />

Composable

The useFlash composable gives you direct access to the flash message state if you need to build a completely custom UI from scratch:

<script setup>
import { useFlash } from 'inertia-flash-vue';

const { visible, dismiss } = useFlash({ maxVisible: 5 });
</script>

<template>
    <div v-for="msg in visible" :key="msg.id">
        <strong v-if="msg.title">{{ msg.title }}</strong>
        <p>{{ msg.message }}</p>
        <button v-if="msg.dismissible" @click="dismiss(msg.id)">Dismiss</button>
    </div>
</template>

Message shape

Each message from the server has the following shape (configured in Laravel):

interface FlashMessage {
    id: string; // UUID generated server-side
    type: 'success' | 'error' | 'warning' | 'info';
    message: string; // Main text (required)
    title: string | null; // Optional heading
    duration: number; // ms before auto-dismiss (0 = persistent)
    dismissible: boolean; // Show close button
    meta: Record<string, unknown>; // Arbitrary data from ->meta([...])
}

All of these fields are set by the Laravel package — see the backend documentation for the full fluent API.

TypeScript

All types are exported:

import type {
    FlashMessage,
    FlashType,
    FlashPosition,
    FlashUI,
    FlashToastUI,
    FlashContainerUI,
    FlashVariantClasses,
} from 'inertia-flash-vue';

License

MIT License. See LICENSE for more information.

Credits