Skip to content

Support stable Inertia.js v3 in inertia-sails and templates #192

@DominusKelvin

Description

@DominusKelvin

Summary

Inertia.js v3 is now stable enough for Boring Stack investigation.

Verified on 2026-05-18:

  • @inertiajs/core, @inertiajs/react, @inertiajs/vue3, and @inertiajs/svelte publish 3.1.1 as latest.
  • The npm legacy tag points at 2.3.23, so v2 is still available while v3 is the active line.
  • v3.0.0 shipped on 2026-03-25, and v3.1.1 shipped on 2026-05-07.

This issue tracks the work needed to make inertia-sails and the Boring Stack templates compatible with stable Inertia v3. The goal is to first support a normal client-rendered Inertia app, then treat SSR/Rsbuild plugin work as a follow-up phase.

Current Repo State

  • packages/inertia-sails/package.json is 1.3.3 and implements the current v2-oriented Sails adapter.
  • Templates currently pin Inertia client packages to v2 ranges:
    • templates/mellow-vue: @inertiajs/vue3@^2.0.3, inertia-sails@^1.0.1
    • templates/mellow-react: @inertiajs/react@^2.1.2, inertia-sails@^1.1.0
    • templates/mellow-svelte: @inertiajs/svelte@^2.0.3, inertia-sails@^1.1.0
    • templates/ascent-vue: @inertiajs/vue3@^2.2.15, inertia-sails@^1.1.0
    • templates/ascent-react: @inertiajs/react@^2.2.15, inertia-sails@^1.1.0
  • The framework versions are mostly ready for v3 minimums: React templates already use React 19, Svelte uses Svelte 5, and Vue templates use Vue 3.

Audit Notes from inertia-sails

inertia-sails already has useful protocol pieces:

  • Page rendering through lib/render.js and lib/helpers/build-page-object.js
  • Request-scoped shared props and locals through lib/helpers/request-context.js
  • Partial reload headers and prop filtering
  • Optional, always, deferred, merge, deep merge, scroll, and once prop wrappers
  • Validation error redirect handling
  • X-Inertia-Location handling for location visits
  • History encryption and clear-history request flags
  • Flash data support
  • Testing helpers in packages/inertia-sails/test.js

The main v3 gaps are protocol shape, initial HTML boot data, shared prop metadata, richer merge metadata, asset-version mismatch behavior, and tests/docs.

Phase 1 - Stable v3 Client Compatibility

inertia-sails Protocol Work

  • Update lib/helpers/build-page-object.js so clearHistory and encryptHistory are only included in the page object when their value is true. v3 protocol marks both as omitted unless enabled.
  • Add top-level sharedProps metadata to the page object. This should list top-level keys registered through sails.inertia.share() and sails.inertia.shareGlobally() so v3 instant visits can carry shared props correctly.
  • Add or verify asset-version mismatch handling. inertia-sails defines X-Inertia-Version, and auto-generates versions from the Shipwright manifest, but the adapter should compare incoming X-Inertia-Version against the current version and return a 409 with X-Inertia-Location when assets are stale.
  • Review lib/location.js against the v3 protocol. Existing 409 location visit and 303 redirects for PUT/PATCH/DELETE look aligned, but this should be covered by tests.
  • Extend merge support in lib/props/merge-prop.js and lib/props/resolve-merge-props.js for v3 metadata:
    • mergeProps
    • prependProps
    • deepMergeProps
    • matchPropsOn
    • nested prop paths
    • reset behavior through X-Inertia-Reset
  • Review whether preserveFragment should be exposed by inertia-sails, likely as a request-scoped helper similar to clearHistory().
  • Review deferred prop rescue support. v3 protocol includes rescuedProps; current deferred props implementation does not appear to expose rescue metadata.
  • Keep the existing validation error flow, but add v3 regression coverage around X-Inertia-Error-Bag and redirect-back behavior.
  • Update packages/inertia-sails/test.js with assertions for new metadata: omitted false history flags, sharedProps, prependProps, matchPropsOn, rescuedProps if implemented, and asset-version mismatch responses.
  • Decide package versioning. This likely needs a major inertia-sails release because the adapter output and template boot contract change.

Template Work

  • Replace initial page boot markup in every views/app.ejs template. v3 uses a JSON script tag instead of the old root data-page attribute.

    <div id="app"></div>
    <script type="application/json" data-page="app"><%- JSON.stringify(page) %></script>

    Affected files:

    • templates/ascent-react/views/app.ejs
    • templates/ascent-vue/views/app.ejs
    • templates/mellow-react/views/app.ejs
    • templates/mellow-svelte/views/app.ejs
    • templates/mellow-vue/views/app.ejs
  • Update packages/inertia-sails/README.md, which still documents <div id="app" data-page="...">.

  • Bump template dependencies to stable v3 ranges, probably @inertiajs/*@^3.1.1 once the adapter changes land.

  • Bump template inertia-sails dependency to the new compatible adapter release.

  • Regenerate or update template lockfiles after dependency changes.

  • Verify Rsbuild/Rspack page resolution with v3 ESM packages. Templates currently use this resolver inside bundled client code:

    resolve: (name) => require(`./pages/${name}`)

    This may still work through Rspack, but it needs a real build/runtime check.

  • If the require() resolver breaks under v3 ESM, switch templates to an Rsbuild-compatible dynamic import/page resolver.

  • Check for removed/renamed v3 client APIs. Initial grep did not find current template usage of router.cancel(), hideProgress(), revealProgress(), invalid, or exception event handlers, but keep this in the upgrade checklist.

create-sails / Generator Work

  • Update any generator/template source that emits Inertia root markup or client imports.
  • Ensure generated React, Vue, and Svelte apps use the new compatible package ranges.
  • Add generator coverage or smoke tests so new apps boot with v3.

Phase 2 - Error Pages and Exceptions

  • Design a Sails-friendly equivalent of Inertia v3 exception rendering for 403, 404, 500, and 503.
  • Preserve the existing development error modal behavior for Inertia requests where appropriate.
  • Add a config option under config/inertia.js, for example handleExceptions, that can return an Inertia page response or fall through to default Sails responses.
  • Add default error page components to templates if we choose to ship this as part of the v3 support story.

Phase 3 - SSR and Rsbuild Plugin Investigation

Do not block basic v3 support on SSR. Track this as a follow-up once client-rendered v3 works.

  • Compare @inertiajs/vite v3 behavior against Shipwright/Rsbuild needs.
  • Decide whether we need an @inertiajs/rsbuild or Boring Stack-specific Rsbuild plugin.
  • If needed, prototype SSR entry handling, dev SSR endpoint, production SSR build, and CSS collection through Rsbuild/Shipwright.
  • Update inertia-sails SSR rendering only after the build-system story is clear.

Acceptance Criteria

  • inertia-sails emits a v3-compatible page object.
  • Initial non-Inertia HTML responses boot from the v3 JSON script tag.
  • Inertia XHR responses, partial reloads, validation redirects, location visits, flash props, once props, deferred props, merge props, scroll props, and history flags have focused tests.
  • At least one React, Vue, and Svelte template boots successfully with @inertiajs/*@3.x.
  • Generated apps from create-sails use the v3-compatible template path.
  • Docs and README examples no longer show the v2 data-page root attribute.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestinertia-sailsThe Inertia adapter for Sails

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions