Skip to content

Add View Transition API Support to Inertia.js #2421

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 4 commits into
base: master
Choose a base branch
from

Conversation

Saad5400
Copy link

@Saad5400 Saad5400 commented Jul 3, 2025

Add View Transition API Support to Inertia.js

Disclaimer: I was unable to comprehensively test this feature. Some help in testing would be appreciated!

Description

This pull request adds native support for the View Transition API to Inertia.js, enabling smooth animated transitions between page navigations while maintaining the framework's server-driven approach.

Problem Statement

Currently, Inertia.js provides instant page transitions but lacks support for smooth animations between pages. Developers who want animated transitions must implement custom solutions that are complex, error-prone, and don't integrate well with Inertia's visit lifecycle.

Solution

This implementation adds comprehensive View Transition API support through:

Core Changes

  1. New Type Definitions (packages/core/src/types.ts)

    • ViewTransitionOptions interface for configuration
    • Extended Visit type to include viewTransition property
  2. ViewTransitionManager (packages/core/src/viewTransition.ts)

    • Browser feature detection with graceful fallbacks
    • Lifecycle management for view transitions
    • Error handling and callback execution
  3. Router Integration (packages/core/src/router.ts)

    • setDefaultViewTransition() method for global configuration
    • Enhanced all visit methods (get, post, put, patch, delete, visit) to support view transition options
    • Proper merging of default and per-visit configurations
  4. Response Integration (packages/core/src/response.ts)

    • Wrapped page setting logic with view transition API
    • Maintains full backward compatibility
  5. Event System (packages/core/src/events.ts)

    • New events: inertia:view-transition-start and inertia:view-transition-end
    • Consistent with existing Inertia event patterns

Benefits to End Users

1. Enhanced User Experience

  • Smooth, native browser animations between pages
  • Professional-looking transitions with minimal effort
  • Improved perceived performance

2. Progressive Enhancement

  • Works in modern browsers with View Transition support (Chrome 111+, Edge 111+, Safari 18+)
  • Graceful fallback in older browsers (no transitions, but no breakage)
  • Zero impact on existing applications

3. Simple API

// Global configuration
router.setDefaultViewTransition({ enabled: true })

// Per-visit configuration
router.visit('/users', { 
  viewTransition: { enabled: true } 
})

// Framework integration
<Link href="/profile" viewTransition={{ enabled: true }}>
  Profile
</Link>

4. Flexible Configuration

  • Global defaults with per-visit overrides
  • Lifecycle callbacks for custom logic
  • Event listeners for advanced use cases

Backward Compatibility

Fully backward compatible - No breaking changes to existing APIs
Zero impact - Existing applications continue to work without modification
Opt-in - View transitions are disabled by default

Implementation Details

Browser Support Strategy

  • Feature Detection: Checks for document.startViewTransition support
  • Graceful Fallback: Falls back to normal page updates when unsupported
  • Progressive Enhancement: Applications work everywhere, enhanced where possible

Configuration Options

  • enabled: Boolean to enable/disable transitions
  • updateCallback: Custom callback during transition
  • onViewTransitionStart: Called when transition begins
  • onViewTransitionEnd: Called when transition completes
  • onViewTransitionError: Called if transition fails

Usage Patterns

Global Configuration:

import { router } from '@inertiajs/core'
router.setDefaultViewTransition({ enabled: true })

Per-Visit Configuration:

router.visit('/users', {
  viewTransition: { enabled: true }
})

Framework Integration:

// React
<Link href="/profile" viewTransition={{ enabled: true }}>
  Profile
</Link>

// Svelte
<a href="/profile" use:inertia={{ viewTransition: { enabled: true } }}>
  Profile
</a>

CSS Styling:

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.3s;
}

Why This Doesn't Break Existing Features

  1. Additive Changes Only: All new functionality is opt-in
  2. Default Behavior Unchanged: Existing visits work exactly as before
  3. Graceful Degradation: Unsupported browsers get normal behavior
  4. Type Safety: All additions are properly typed without affecting existing types
  5. Event System Integration: New events follow existing patterns

How This Makes Building Web Applications Easier

  1. Native Browser APIs: Leverages optimized browser functionality
  2. Minimal Configuration: Works with a single boolean flag
  3. Framework Agnostic: Works consistently across React, Vue, Svelte
  4. CSS-Only Styling: No JavaScript required for animations
  5. Professional UX: Instant professional-quality transitions

@pascalbaljet
Copy link
Member

Thanks for this! I definitely want to add support for this, but I feel this PR is a little over-engineered, maybe. Why do we need the inertia:view-transition-start and inertia:view-transition-end events?

@pascalbaljet pascalbaljet added the needs more info/work Needs more info from the author or additional work to get merged label Jul 4, 2025
@Saad5400
Copy link
Author

Saad5400 commented Jul 6, 2025

Honestly, we may not need them currently. I'm new to this so it's ok if I should remove them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs more info/work Needs more info from the author or additional work to get merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants