# Inertia.js Inertia.js is a modern framework that allows you to build single-page applications (SPAs) using classic server-side routing and controllers. It eliminates the need for a separate API by allowing your server-side framework (Laravel, Rails, etc.) to render pages as JavaScript components (React, Vue, or Svelte) while maintaining the benefits of server-side routing, controllers, and middleware. The library provides a seamless bridge between server-side and client-side code, offering features like automatic page transitions, form handling with validation, prefetching, polling, infinite scroll, and deferred props loading. It supports React, Vue 3, and Svelte adapters, each providing framework-specific components and hooks that integrate naturally with the respective ecosystem. ## Core API ### createInertiaApp - Application Bootstrap The `createInertiaApp` function initializes an Inertia application, setting up component resolution, page rendering, and optional progress indicators. It handles both client-side rendering (CSR) and server-side rendering (SSR) configurations. ```tsx // React CSR Setup (main.tsx) import { createInertiaApp } from '@inertiajs/react' import { createRoot } from 'react-dom/client' createInertiaApp({ resolve: (name) => { const pages = import.meta.glob('./Pages/**/*.tsx', { eager: true }) return pages[`./Pages/${name}.tsx`] }, setup({ el, App, props }) { createRoot(el).render() }, progress: { delay: 250, color: '#29d', includeCSS: true, showSpinner: false, }, defaults: { form: { recentlySuccessfulDuration: 2000, }, prefetch: { cacheFor: '30s', hoverDelay: 75, }, }, }) // React SSR Setup (ssr.tsx) import { createInertiaApp } from '@inertiajs/react' import { renderToString } from 'react-dom/server' export default function render(page) { return createInertiaApp({ page, render: renderToString, resolve: (name) => { const pages = import.meta.glob('./Pages/**/*.tsx', { eager: true }) return pages[`./Pages/${name}.tsx`] }, setup({ App, props }) { return }, }) } ``` ### router - Navigation and Visits The `router` object provides methods for programmatic navigation, including `visit`, `get`, `post`, `put`, `patch`, `delete`, `reload`, and `prefetch`. It manages page transitions, history, and request lifecycle events. ```tsx import { router } from '@inertiajs/react' // Basic navigation router.visit('/users', { method: 'get', data: { search: 'john' }, preserveState: true, preserveScroll: true, only: ['users'], // Partial reload - only fetch 'users' prop except: ['notifications'], // Exclude specific props replace: true, // Replace history entry headers: { 'X-Custom-Header': 'value' }, onBefore: (visit) => confirm('Navigate away?'), onStart: (visit) => console.log('Starting...'), onProgress: (progress) => console.log(`${progress.percentage}%`), onSuccess: (page) => console.log('Success!', page), onError: (errors) => console.error('Errors:', errors), onCancel: () => console.log('Cancelled'), onFinish: (visit) => console.log('Finished'), }) // HTTP method shortcuts router.get('/users', { page: 1 }) router.post('/users', { name: 'John', email: 'john@example.com' }) router.put('/users/1', { name: 'John Updated' }) router.patch('/users/1', { status: 'active' }) router.delete('/users/1') // Reload current page with specific props router.reload({ only: ['notifications'] }) // Prefetch a page for faster navigation router.prefetch('/dashboard', {}, { cacheFor: '5m', cacheTags: ['dashboard'] }) // Flush prefetch cache router.flush('/dashboard') router.flushAll() router.flushByCacheTags(['dashboard']) // Cancel in-flight requests router.cancelAll({ async: true, prefetch: true, sync: true }) // History management router.remember({ scroll: 100 }, 'scroll-position') const saved = router.restore('scroll-position') router.clearHistory() // Client-side state manipulation router.replace({ props: (current) => ({ ...current, count: current.count + 1 }) }) router.push({ url: '/new-url', props: { data: 'value' } }) router.replaceProp('user.name', 'New Name') router.appendToProp('items', newItem) router.prependToProp('items', newItem) // Flash messages router.flash('success', 'Operation completed!') router.flash({ success: 'Saved!', error: null }) // Global event listeners const removeListener = router.on('navigate', (event) => { console.log('Navigated to:', event.detail.page.url) }) // Later: removeListener() // Polling const poll = router.poll(5000, { only: ['notifications'] }, { keepAlive: false }) poll.stop() poll.start() ``` ## React Components ### Link - Client-Side Navigation The `Link` component creates links that perform client-side navigation without full page reloads. It supports prefetching, preserve options, and all standard anchor attributes. ```tsx import { Link } from '@inertiajs/react' function Navigation() { return ( ) } ``` ### useForm - Form State Management The `useForm` hook provides comprehensive form state management with validation, error handling, progress tracking, and submission. It supports both standard Inertia forms and precognitive (real-time) validation. ```tsx import { useForm } from '@inertiajs/react' function CreateUserForm() { const form = useForm({ name: '', email: '', password: '', avatar: null as File | null, roles: [] as string[], }) function handleSubmit(e: React.FormEvent) { e.preventDefault() form.post('/users', { onSuccess: () => form.reset(), onError: (errors) => console.log('Validation errors:', errors), forceFormData: true, // Force FormData for file uploads }) } return (
form.setData('name', e.target.value)} /> {form.errors.name && {form.errors.name}} form.setData('email', e.target.value)} /> {form.errors.email && {form.errors.email}} form.setData('password', e.target.value)} /> form.setData('avatar', e.target.files?.[0] ?? null)} /> {/* Progress indicator for file uploads */} {form.progress && ( )} {/* Status indicators */} {form.wasSuccessful && Saved!} {form.recentlySuccessful && Just saved!} {form.isDirty && Unsaved changes} {form.hasErrors && Please fix errors} ) } // With remember key (persists form state across page visits) function RememberedForm() { const form = useForm('create-user-form', { name: '', email: '', }) // Exclude sensitive fields from being remembered form.dontRemember('password') return
{/* ... */}
} // With precognitive (real-time) validation function PrecognitiveForm() { const form = useForm('post', '/users', { name: '', email: '', }) .withPrecognition('post', '/users') .setValidationTimeout(500) .validateFiles() return (
{ e.preventDefault(); form.submit() }}> form.setData('name', e.target.value)} onBlur={(e) => form.validate('name')} /> {form.invalid('name') && {form.errors.name}} {form.valid('name') && Valid!} {form.validating && Validating...} form.setData('email', e.target.value)} onBlur={(e) => form.validate('email')} /> {form.touched('email') && form.errors.email && ( {form.errors.email} )}
) } // Using transform to modify data before submission function TransformExample() { const form = useForm({ date: new Date() }) form.transform((data) => ({ ...data, date: data.date.toISOString(), })) return
{/* ... */}
} ``` ### Form - Declarative Form Component The `Form` component provides a declarative way to handle forms with automatic data collection from native form elements, built-in validation, and submission handling. ```tsx import { Form, useFormContext } from '@inertiajs/react' function ContactForm() { return (
{({ errors, processing, isDirty, wasSuccessful, validate, submit }) => ( <> validate('name')} /> {errors.name && {errors.name}} validate('email')} /> {errors.email && {errors.email}}