Skip to content

Add router configuration for displaying modal on non-Inertia responses #2332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Andy9822
Copy link

@Andy9822 Andy9822 commented Apr 30, 2025

Description

This PR adds a new configuration option showModalOnNonInertiaResponse to the createInertiaApp function in all framework adapters (React, Vue, Svelte). This option allows developers to disable the automatic modal display when receiving non-Inertia responses and handle them in a custom way.

Problem

Currently, when a non-Inertia response is received (e.g., a regular JSON response instead of an Inertia response), Inertia automatically shows a modal with the response data. While this is helpful during development for debugging, it can create a poor user experience in production if not properly handled.

Proposed Solution

I've implemented this feature by adding a configuration option to the modal system. This approach aligns well with the existing architecture since the modal functionality is already encapsulated in its own module.

The implementation:

  1. Adds a new ModalConfig type in packages/core/src/types.ts
  2. Adds setupModal and getConfig methods to handle modal configuration
  3. Modifies the modal behavior to respect the configuration setting
  4. Adds the new option to all framework adapters' createInertiaApp functions

The modal configuration is set up during the client-side initialization in each framework adapter, ensuring consistent behavior across React, Vue, and Svelte.

Usage Example

createInertiaApp({
  resolve: (name) => import(`./Pages/${name}`),
  setup({ el, App, props }) {
    render(<App {...props} />, el)
  },
  showModalOnNonInertiaResponse: false, // Disable the modal
})

With this option disabled, developers can handle non-Inertia responses by listening to the inertia:invalid event:

document.addEventListener("inertia:invalid", (event) => {
  console.error('Received non-Inertia response:', event.detail.response)
  // Custom error handling logic
})

Benefits

  1. Better Production UX: The automatic modal can be disruptive in production environments. This option allows developers to handle non-Inertia responses in a more user-friendly way.

  2. Custom Error Handling: Developers can implement their own error handling logic based on their application's needs.

  3. Maintains Development Experience: The modal is still shown by default, making it easy to debug during development.

  4. Consistent Implementation: The configuration is handled uniformly across all framework adapters through the core modal module.

Additional Context

The modal error handling is very helpful during local development as it immediately shows what's wrong with the response. However, if this behavior accidentally makes it into production, it creates a very poor user experience. Users would see a technical error modal instead of a graceful error page or notification.

By providing this configuration option, we give developers the flexibility to handle these responses appropriately in their production environments while maintaining the helpful debugging experience during development.

Implementation Notes

The implementation uses the core modal module's configuration system rather than the router, which provides several advantages:

  1. Direct control over the modal behavior where it's most relevant
  2. Cleaner separation of concerns between routing and UI feedback
  3. Simplified testing and maintenance since the configuration is closer to the feature it controls

The configuration is applied consistently across all framework adapters using the setupModal function from the core package, ensuring uniform behavior regardless of the framework being used.

Closes #2331

@Andy9822 Andy9822 force-pushed the 2331-add-option-to-disable-modal-on-non-inertia-response-errors branch 2 times, most recently from dc7a3f9 to dfcdfb3 Compare April 30, 2025 04:40
@@ -90,7 +90,9 @@ export class Response {
}

if (fireInvalidEvent(response)) {
return modal.show(response.data)
if (modal.getConfig().showOnNonInertiaResponse) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this logic could be moved inside the modal.show so the caller doesn't need to know about this config or any business rule

@Andy9822 Andy9822 force-pushed the 2331-add-option-to-disable-modal-on-non-inertia-response-errors branch from dfcdfb3 to 9050608 Compare April 30, 2025 04:44
@@ -82,6 +84,10 @@ export default async function createInertiaApp<SharedProps extends PageProps = P

let head = []

if (!isServer) {
setupModal({ showOnNonInertiaResponse: showModalOnNonInertiaResponse })
Copy link
Author

@Andy9822 Andy9822 Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative Approach:

if we wanted to follow the same "API" used for the progress configs, we could instead have a modal = {} props and then call setupModal(modal)

Copy link
Author

@Andy9822 Andy9822 Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A usage example of the alternative proposal would then look like:

createInertiaApp({
 modal: {
   showOnNonInertiaResponse: false
 },
 progress: { 
   delay: 300,
   color: '#29d'
 },
 resolve: (name) => import(`./Pages/${name}`),
 setup({ el, App, props }) {
   render(<App {...props} />, el)
 }
})

@Andy9822
Copy link
Author

hey @joetannenbaum , do you have interest in this contribution?
I wonder if there's anything else I could add or adapt - if this looks like something you'd okay in merging

@Andy9822 Andy9822 changed the title Add router configuration for modal display on non-Inertia responses Add router configuration for displaying modal on non-Inertia responses May 20, 2025
@pascalbaljet
Copy link
Contributor

I think it's a good thing to have this option as this is the only place where Inertia is quite opinionated when it comes to UI. I'm not sure about the showModalOnNonInertiaResponse though. I opt for an errorModal key that defaults to true. That leaves the door open for a config object in the future.

Have you seen the documentation on handling errors in production? You can also redirect back (with a message) or render a dedicated error page: https://inertiajs.com/error-handling#production

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing option to disable modal on non-Inertia responses
2 participants