promovaweb/laravel-starter-kit · Archived

inertia-react-development

Develops Inertia.js v3 React client-side applications.

First seen Jul 29, 2026

Installation

$ npx skills add promovaweb/laravel-starter-kit --skill inertia-react-development

Summary

  • Develops Inertia.js v3 React client-side applications.
  • Activates when creating React pages, forms, or navigation; using <Link>, <Form>, useForm, useHttp, setLayoutProps, or router; working with deferred props, prefetching, optimistic updates, instant visits, or polling; or when user mentions React with Inertia, React pages, React forms, or React navigation.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from promovaweb/laravel-starter-kit.

npx skills add promovaweb/laravel-starter-kit

Browse all from promovaweb/laravel-starter-kit

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License MIT
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

LicenseMIT
More metadata
author
laravel

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 13,796 B
  • docs SUMMARY.md 392 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Inertia React Development

When to Apply

Activate this skill when:

  • Creating or modifying React page components for Inertia
  • Working with forms in React (using <Form>, useForm, or useHttp)
  • Implementing client-side navigation with <Link> or router
  • Using v3 features: deferred props, prefetching, optimistic updates, instant visits, layout props, HTTP requests, WhenVisible, InfiniteScroll, once props, flash data, or polling
  • Building React-specific features with the Inertia protocol

Documentation

Use search-docs for detailed Inertia v3 React patterns and documentation.

Basic Usage

Page Components Location

React page components should be placed in the resources/js/pages directory.

Page Component Structure

<!-- Basic React Page Component -->

export default function UsersIndex({ users }) {
    return (
        <div>
            <h1>Users</h1>
            <ul>
                {users.map(user => <li key={user.id}>{user.name}</li>)}
            </ul>
        </div>
    )
}

Client-Side Navigation

Basic Link Component

Use <Link> for client-side navigation instead of traditional <a> tags:

<!-- Inertia React Navigation -->

import { Link, router } from '@inertiajs/react'

<Link href="/">Home</Link>
<Link href="/users">Users</Link>
<Link href={`/users/${user.id}`}>View User</Link>

Link with Method

<!-- Link with POST Method -->

import { Link } from '@inertiajs/react'

<Link href="/logout" method="post" as="button">
    Logout
</Link>

Prefetching

Prefetch pages to improve perceived performance:

<!-- Prefetch on Hover -->

import { Link } from '@inertiajs/react'

<Link href="/users" prefetch>
    Users
</Link>

Programmatic Navigation

<!-- Router Visit -->

import { router } from '@inertiajs/react'

function handleClick() {
    router.visit('/users')
}

// Or with options
router.visit('/users', {
    method: 'post',
    data: { name: 'John' },
    onSuccess: () => console.log('Success!'),
})

Form Handling

Form Component (Recommended)

The recommended way to build forms is with the <Form> component:

<!-- Form Component Example -->

import { Form } from '@inertiajs/react'

export default function CreateUser() {
    return (
        <Form action="/users" method="post">
            {({ errors, processing, wasSuccessful }) => (
                <>
                    <input type="text" name="name" />
                    {errors.name && <div>{errors.name}</div>}

                    <input type="email" name="email" />
                    {errors.email && <div>{errors.email}</div>}

                    <button type="submit" disabled={processing}>
                        {processing ? 'Creating...' : 'Create User'}
                    </button>

                    {wasSuccessful && <div>User created!</div>}
                </>
            )}
        </Form>
    )
}

Form Component With All Props

<!-- Form Component Full Example -->

import { Form } from '@inertiajs/react'

<Form action="/users" method="post">
    {({
        errors,
        hasErrors,
        processing,
        progress,
        wasSuccessful,
        recentlySuccessful,
        clearErrors,
        resetAndClearErrors,
        defaults,
        isDirty,
        reset,
        submit
    }) => (
        <>
            <input type="text" name="name" defaultValue={defaults.name} />
            {errors.name && <div>{errors.name}</div>}

            <button type="submit" disabled={processing}>
                {processing ? 'Saving...' : 'Save'}
            </button>

            {progress && (
                <progress value={progress.percentage} max="100">
                    {progress.percentage}%
                </progress>
            )}

            {wasSuccessful && <div>Saved!</div>}
        </>
    )}
</Form>

Form Component Reset Props

The <Form> component supports automatic resetting:

  • resetOnError - Reset form data when the request fails
  • resetOnSuccess - Reset form data when the request succeeds
  • setDefaultsOnSuccess - Update default values on success

Use the search-docs tool with a query of form component resetting for detailed guidance.

<!-- Form with Reset Props -->

import { Form } from '@inertiajs/react'

<Form
    action="/users"
    method="post"
    resetOnSuccess
    setDefaultsOnSuccess
>
    {({ errors, processing, wasSuccessful }) => (
        <>
            <input type="text" name="name" />
            {errors.name && <div>{errors.name}</div>}

            <button type="submit" disabled={processing}>
                Submit
            </button>
        </>
    )}
</Form>

Forms can also be built using the useForm helper for more programmatic control. Use the search-docs tool with a query of useForm helper for guidance.

useForm Hook

For more programmatic control or to follow existing conventions, use the useForm hook:

<!-- useForm Hook Example -->

import { useForm } from '@inertiajs/react'

export default function CreateUser() {
    const { data, setData, post, processing, errors, reset } = useForm({
        name: '',
        email: '',
        password: '',
    })

    function submit(e) {
        e.preventDefault()
        post('/users', {
            onSuccess: () => reset('password'),
        })
    }

    return (
        <form onSubmit={submit}>
            <input
                type="text"
                value={data.name}
                onChange={e => setData('name', e.target.value)}
            />
            {errors.name && <div>{errors.name}</div>}

            <input
                type="email"
                value={data.email}
                onChange={e => setData('email', e.target.value)}
            />
            {errors.email && <div>{errors.email}</div>}

            <input
                type="password"
                value={data.password}
                onChange={e => setData('password', e.target.value)}
            />
            {errors.password && <div>{errors.password}</div>}

            <button type="submit" disabled={processing}>
                Create User
            </button>
        </form>
    )
}

Inertia v3 Features

HTTP Requests

Use the useHttp hook for standalone HTTP requests that do not trigger Inertia page visits. It provides the same developer experience as useForm, but for plain JSON endpoints.

<!-- useHttp Example -->

import { useHttp } from '@inertiajs/react'

export default function Search() {
    const { data, setData, get, processing } = useHttp({
        query: '',
    })

    function search(e) {
        setData('query', e.target.value)
        get('/api/search', {
            onSuccess: (response) => {
                console.log(response)
            },
        })
    }

    return (
        <>
            <input value={data.query} onChange={search} />
            {processing && <div>Searching...</div>}
        </>
    )
}

Optimistic Updates

Apply data changes instantly before the server responds, with automatic rollback on failure:

<!-- Optimistic Update with Router -->

import { router } from '@inertiajs/react'

function like(post) {
    router.optimistic((props) => ({
        post: {
            ...props.post,
            likes: props.post.likes + 1,
        },
    })).post(`/posts/${post.id}/like`)
}

Optimistic updates also work with useForm and the <Form> component:

<!-- Optimistic Update with Form Component -->

import { Form } from '@inertiajs/react'

<Form
    action="/todos"
    method="post"
    optimistic={(props, data) => ({
        todos: [...props.todos, { id: Date.now(), name: data.name, done: false }],
    })}
>
    <input type="text" name="name" />
    <button type="submit">Add Todo</button>
</Form>

Instant Visits

Navigate to a new page immediately without waiting for the server response. The target component renders right away with shared props, while page-specific props load in the background.

<!-- Instant Visit with Link -->

import { Link } from '@inertiajs/react'

<Link href="/dashboard" component="Dashboard">Dashboard</Link>

<Link
    href="/posts/1"
    component="Posts/Show"
    pageProps={{ post: { id: 1, title: 'My Post' } }}
>
    View Post
</Link>

Layout Props

Share dynamic data between pages and persistent layouts:

<!-- Layout Props in Layout -->

export default function Layout({ title = 'My App', showSidebar = true, children }) {
    return (
        <>
            <header>{title}</header>
            {showSidebar && <aside>Sidebar</aside>}
            <main>{children}</main>
        </>
    )
}

<!-- Setting Layout Props from Page -->

import { setLayoutProps } from '@inertiajs/react'

export default function Dashboard() {
    setLayoutProps({
        title: 'Dashboard',
        showSidebar: false,
    })

    return <h1>Dashboard</h1>
}

Deferred Props

Use deferred props to load data after initial page render:

<!-- Deferred Props with Empty State -->

export default function UsersIndex({ users }) {
    return (
        <div>
            <h1>Users</h1>
            {!users ? (
                <div className="animate-pulse">
                    <div className="h-4 bg-gray-200 rounded w-3/4 mb-2"></div>
                    <div className="h-4 bg-gray-200 rounded w-1/2"></div>
                </div>
            ) : (
                <ul>
                    {users.map(user => (
                        <li key={user.id}>{user.name}</li>
                    ))}
                </ul>
            )}
        </div>
    )
}

Polling

Use the usePoll hook to automatically refresh data at intervals. It handles cleanup on unmount and throttles polling when the tab is inactive.

<!-- Basic Polling -->

import { usePoll } from '@inertiajs/react'

export default function Dashboard({ stats }) {
    usePoll(5000)

    return (
        <div>
            <h1>Dashboard</h1>
            <div>Active Users: {stats.activeUsers}</div>
        </div>
    )
}

<!-- Polling With Request Options and Manual Control -->

import { usePoll } from '@inertiajs/react'

export default function Dashboard({ stats }) {
    const { start, stop } = usePoll(5000, {
        only: ['stats'],
        onStart() {
            console.log('Polling request started')
        },
        onFinish() {
            console.log('Polling request finished')
        },
    }, {
        autoStart: false,
        keepAlive: true,
    })

    return (
        <div>
            <h1>Dashboard</h1>
            <div>Active Users: {stats.activeUsers}</div>
            <button onClick={start}>Start Polling</button>
            <button onClick={stop}>Stop Polling</button>
        </div>
    )
}
  • autoStart (default true) - set to false to start polling manually via the returned start() function
  • keepAlive (default false) - set to true to prevent throttling when the browser tab is inactive

WhenVisible

Lazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:

<!-- WhenVisible Example -->

import { WhenVisible } from '@inertiajs/react'

export default function Dashboard({ stats }) {
    return (
        <div>
            <h1>Dashboard</h1>

            <WhenVisible data="stats" buffer={200} fallback={<div className="animate-pulse">Loading stats...</div>}>
                {({ fetching }) => (
                    <div>
                        <p>Total Users: {stats.total_users}</p>
                        <p>Revenue: {stats.revenue}</p>
                        {fetching && <span>Refreshing...</span>}
                    </div>
                )}
            </WhenVisible>
        </div>
    )
}

InfiniteScroll

Automatically load additional pages of paginated data as users scroll:

<!-- InfiniteScroll Example -->

import { InfiniteScroll } from '@inertiajs/react'

export default function Users({ users }) {
    return (
        <InfiniteScroll data="users">
            {users.data.map(user => (
                <div key={user.id}>{user.name}</div>
            ))}
        </InfiniteScroll>
    )
}

The server must use Inertia::scroll() to configure the paginated data. Use the search-docs tool with a query of infinite scroll for detailed guidance on buffers, manual loading, reverse mode, and custom trigger elements.

Server-Side Patterns

Server-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.

Common Pitfalls

  • Using traditional <a> links instead of Inertia's <Link> component (breaks SPA behavior)
  • Forgetting to add loading states (skeleton screens) when using deferred props
  • Not handling the undefined state of deferred props before data loads
  • Using <form> without preventing default submission (use <Form> component or e.preventDefault())
  • Forgetting to check if <Form> component is available in your Inertia version
  • Using router.cancel() instead of router.cancelAll() (v3 breaking change)
  • Using router.on('invalid', ...) or router.on('exception', ...) instead of the renamed httpException and networkError events