Skip to content

Inertia Modal

Inertia Modal is a powerful library that enables you to render any Inertia page as a modal dialog. It seamlessly integrates with your existing Inertia Rails application, allowing you to create modal workflows without the complexity of managing modal state manually.

Here's a summary of the features:

  • Supports React and Vue
  • Zero backend configuration
  • Super simple frontend API
  • Support for Base Route / URL
  • Modal and slideover support
  • Headless support
  • Nested/stacked modals support
  • Reusable modals
  • Multiple sizes and positions
  • Reload props in modals
  • Easy communication between nested/stacked modals
  • Highly configurable

While you can use Inertia Modal without changes on the backend, we recommend using the Rails gem inertia_rails-contrib to enhance your modals with base URL support. This ensures that your modals are accessible, SEO-friendly, and provide a better user experience.

NOTE

Svelte 5 is not yet supported by Inertia Modal.

Installation

1. Install the NPM Package

bash
npm install @inertiaui/modal-vue

2. Configure Inertia

Update your Inertia app setup to include the modal plugin:

js
// frontend/entrypoints/inertia.js
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import { renderApp } from '@inertiaui/modal-vue'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
    return pages[`../pages/${name}.vue`]
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) }) 
    createApp({ render: renderApp(App, props) }) 
      .use(plugin)
      .mount(el)
  },
})

3. Tailwind CSS Configuration

For Tailwind CSS v4, add the modal styles to your CSS:

css
/* app/entrypoints/frontend/application.css */
@source "../../../node_modules/@inertiaui/modal-vue";

For Tailwind CSS v3, update your tailwind.config.js:

js
export default {
  content: [
    './node_modules/@inertiaui/modal-vue/src/**/*.{js,vue}',
    // other paths...
  ],
}

Install the inertia_rails-contrib gem to your Rails application to enable base URL support for modals:

bash
bundle add inertia_rails-contrib

Basic example

The package comes with two components: Modal and ModalLink. ModalLink is very similar to Inertia's built-in Link component, but it opens the linked route in a modal instead of a full page load. So, if you have a link that you want to open in a modal, you can simply replace Link with ModalLink.

vue
<script setup>
import { Link } from '@inertiajs/vue3'
import { ModalLink } from '@inertiaui/modal-vue'
</script>

<template>
  <Link href="/users/create">Create User</Link>
  <ModalLink href="/users/create">Create User</ModalLink>
</template>

The page you linked can then use the Modal component to wrap its content in a modal.

vue
<script setup>
import { Modal } from '@inertiaui/modal-vue'
</script>

<template>
  <Modal>
    <h1>Create User</h1>
    <form>
      <!-- Form fields -->
    </form>
  </Modal>
</template>

That's it! There is no need to change anything about your routes or controllers!

Enhanced Usage With Base URL Support

By default, Inertia Modal doesn't change the URL when opening a modal. It just stays on the same page and displays the modal content. However, you may want to change this behavior and update the URL when opening a modal. This has a few benefits:

  • It allows users to bookmark the modal and share the URL with others.
  • The modal becomes part of the browser history, so users can use the back and forward buttons.
  • It makes the modal content accessible to search engines (when using SSR).
  • It allows you to open the modal in a new tab.

NOTE

To enable this feature, you need to use the inertia_rails-contrib gem, which provides base URL support for modals.

Define a Base Route

To define the base route for your modal, you need to use the inertia_modal renderer in your controller instead of the inertia one. It accepts the same arguments as the inertia renderer:

ruby

class UsersController < ApplicationController
  def edit
    render inertia: 'Users/Edit', props: { 
    render inertia_modal: 'Users/Edit', props: { 
      user:,
      roles: -> { Role.all },
    }
  end
end

Then, you can pass the base_url parameter to the inertia_modal renderer to define the base route for your modal:

ruby

class UsersController < ApplicationController
  def edit
    render inertia_modal: 'Users/Edit', props: {
      user:,
      roles: -> { Role.all },
    } 
    }, base_url : users_path 
  end
end

Reusing the Modal URL with different Base Routes

The base_url parameter acts merely as a fallback when the modal is directly opened using a URL. If you open the modal from a different route, the URL will be generated based on the current route.

Open a Modal with a Base Route

Finally, the frontend needs to know that we're using the browser history to navigate between modals. To do this, you need to add the navigate attribute to the ModalLink component:

vue
<template>
  <ModalLink navigate href="/users/create"> Create User </ModalLink>
</template>

Now, when you click the "Create User" link, it will open the modal and update the URL to /users/create.

Further Reading

For advanced usage, configuration options, and additional features, check out the official Inertia Modal documentation.