View Source Changelog
3.0.0-rc3 - 2026-05-30
Added
- First-party pagination support for
inertia_scroll/2. Pass aScrivener.Pagestruct or a Flop{records, %Flop.Meta{}}tuple directly and the entries are placed under the:wrapperkey (default"data") with pagination metadata extracted automatically. Extensible to other libraries via theInertia.Paginatedprotocol, whoseto_scroll/1returns a metadata map that optionally carries the page's:entries. Also adds a:transformoption for serializing each entry before it is rendered, and a:metaoption (a function whose returned map is placed under a"meta"key in the prop, alongside the entries) for surfacing extra pagination data to the page. - Add a
:csp_nonce_assign_keyconfig option. When set, the library reads a Content-Security-Policy nonce from the given connection assign and applies it to the<script>tag used to bootstrap the page data. - The
:match_onoption oninertia_merge/2,inertia_prepend/2, andinertia_deep_merge/2now accepts a list of keys (in addition to a single key) for matching on multiple fields, producing onematchPropsOnentry per key. - Add an
on_error: :ignoreoption toinertia_defer/2,3for graceful failure of deferred props. When a rescued deferred prop's resolver fails during a partial reload, the prop is omitted, its path is reported in therescuedPropspage metadata, and the failure is logged and emitted as a[:inertia, :deferred_prop, :rescue]telemetry event (#75).
Changed
- (Breaking)
inertia_scroll/2now always shapes the prop value as%{<wrapper> => entries}. Previously a%{data:, meta:}map was passed through verbatim; now only the entries under the wrapper key are kept, and any other top-level keys (includingmetaand any sibling fields liketotal_count) are dropped from the prop. Pagination metadata is surfaced viascrollPropsinstead — read pagination state from there. - (Breaking) Renamed the
inertia_scroll/2:metadataoption (added in 2.6.0) to:scroll_metadata, to distinguish it from the new:metaoption (which adds display data to the prop value).:scroll_metadatastill produces thescrollPropsthe client component uses. - (Breaking)
ectois now an optional dependency. TheEcto.Changeseterror serializer is only available when Ecto is present. Apps that pass changesets toassign_errorsand don't already depend on Ecto should add{:ecto, "~> 3.10"}(most Phoenix apps already do). Bare error maps work without Ecto. - (Breaking)
nodejsis now an optional dependency. It's only needed by the default Node.js SSR adapter, so apps using SSR with the default adapter should add{:nodejs, "~> 3.0"}. Apps that don't use SSR (or use a custom:ssr_adapter) no longer pull it in. - (Breaking) Raised minimum versions: Elixir
>= 1.15.0andphoenix_html ~> 4.0.
Removed
- (Breaking) Removed the
Inertia.ScrollMetadataprotocol (added in 2.6.0). Pagination extensibility is now provided by the singleInertia.Paginatedprotocol — implementto_scroll/1(which returns a metadata map, optionally carrying:entries) instead ofto_scroll_metadata/1.
Fixed
- Emit
matchPropsOnas a list of"path.field"strings (e.g.["users.id"]) instead of a%{path => field}map. The Inertia.js client expects an array and callsArray.prototype.findon it, so the previous map shape caused a client-side error when merging props with amatch_onkey.
3.0.0-rc2 - 2026-05-27
Added
- Add a pluggable SSR adapter system. Server-side rendering is now performed through an
Inertia.SSR.Adapterbehaviour, so you can plug in an alternative JavaScript runtime (Bun, a Vite dev server, etc.) in place of the default Node.js process pool by passing a module via the:ssr_adapteroption toInertia.SSR. The defaultInertia.SSR.NodeJSAdapterpreserves the existing behavior (#44). - Add an
:esmoption toInertia.SSRfor using an ECMAScript Module SSR entrypoint. ESM is also auto-detected from a.mjsmodule extension (#44). - The
inertia.installtask now produces a complete, buildable setup for Svelte and Vue, not just React. Because Svelte and Vue single-file components must be compiled by an esbuild plugin — which theesbuildHex package's CLI can't load — the installer drives esbuild from Node (assets/esbuild.config.js) viaesbuild-svelte/unplugin-vue, generates the framework's Inertia entry point, and installs the client packages. inertia.installnow scaffolds a starter page (Home.jsx/Home.vue/Home.svelte) in place of an empty.gitkeep, somix assets.buildsucceeds immediately after install.- Add step-by-step front-end setup guides for React, Svelte, and Vue, each covering both client-side and server-side rendering with esbuild and backed by runnable example apps under
examples/.
Changed
- The
inertia.installtask's React setup now addsnpm installto theassets.setupalias, so client dependencies are restored on a fresh checkout or CI build. - The README no longer centers its client-side and SSR instructions on React. Framework-specific setup (including SSR) now lives in the per-framework guides, while the README covers the shared, framework-agnostic pieces.
Fixed
- The root layout generated by
inertia.installnow loads the JS bundle from/assets/js/app.js, matching esbuild's output directory (previously/assets/app.js, which did not exist).
3.0.0-rc1 - 2026-05-18
Added
- Add nested prop type support with a single recursive resolver. Prop type wrappers (
inertia_defer,inertia_merge,inertia_deep_merge,inertia_optional,inertia_once,inertia_scroll) now work at any nesting depth, including inside closures. For example,inertia_deferinside a closure now correctly generatesdeferredPropsmetadata with dot-notation paths (e.g.,auth.permissions). - Add
assign_shared_prop/3andinertia_share/1to mark props as shared, exposing their keys in thesharedPropspage metadata for the Inertia v3 protocol (#69). - Add
preserve_fragment/1andpreserve_fragment/2functions to instruct the client-side to preserve the URL fragment across server-side redirects (#68). - Add
inertia_prepend/1andinertia_prepend/2for prepending (instead of appending) data during client-side merges. Prepend props appear in bothmergePropsandprependPropsin the page response. Scroll props also respect theX-Inertia-Infinite-Scroll-Merge-Intent: prependheader (#67). - Add
match_on:option toinertia_merge/2,inertia_prepend/2, andinertia_deep_merge/2for client-side deduplication of merged items. Match keys are included inmatchPropsOnpage metadata (#67). - Add
ssr_exclude_pathsconfig option to disable SSR for specific paths. Supports string prefixes and~r//regex patterns (#67). - Add
inertia_flash/1,inertia_page/1,inertia_deferred_props/1,inertia_merge_props/1,inertia_scroll_props/1, andinertia_once_props/1test helpers inInertia.Testing(#67).
Changed
- Breaking: Flash data is now a top-level key in the Inertia page object (
usePage().flash) instead of being nested inside props (usePage().props.flash). This aligns with the Inertia.js frontend conventions and the Laravel adapter (#67). - Breaking: The
<title>tag marker attribute has been renamed frominertiatodata-inertia. If you use the provided<.inertia_title>component, no action is required. If you render the title tag yourself in a custom root layout, update the marker attribute. - Breaking: The initial page payload is now rendered as a
<script type="application/json">tag instead of adata-pageattribute on the container<div>. This matches the only mode supported by Inertia.js v3 (#66). - Set the
Vary: X-Inertiaresponse header on all requests (not just Inertia JSON responses), so HTTP caches can properly differentiate responses (#67). - Remove
axiosfrom the Igniter installer template, since Inertia.js v3 ships with a built-in HTTP client (#66).
Removed
- Breaking: Remove
inertia_lazy/1(deprecated since v2.0.0). Useinertia_optional/1instead (#66).
Fixed
- Persist
clearHistoryacross redirects via the session, matching the existing behavior ofpreserve_fragment. Previously,clear_history(conn)was lost on redirect (#67). - Handle redirects containing URL hash fragments by returning 409 with
X-Inertia-Redirectheader, so the client can perform a full navigation that preserves the fragment (#67). - Redirect Inertia requests that receive a 200 with an empty body back to the referer (or
/), instead of rendering a blank page (#67). - Include
"reset": truein scroll prop metadata when the scroll data path is in theX-Inertia-Resetheader (#67).
2.6.2
Fixed
- Fix CSR fallback crash when SSR returns non-string error (#73).
2.6.1
Fixed
- Fix
onSuccessnot being called whenerrorBagis set and there are no validation errors (#72).
2.6.0
Added
- Add
inertia_scroll/2function to support infinite scroll pagination. Automatically configures merge behavior and extracts pagination metadata for the client-sideInfiniteScrollcomponent. IncludesInertia.ScrollMetadataprotocol for extensible pagination library support (#63). - Add
inertia_once/2function to support once props, which are cached on the client-side and reused across page navigations. Supportsfresh,until, andasoptions for controlling refresh behavior, expiration, and custom keys (#62). - Create an
assets/js/pagesdirectory in the Igniter install task and fix the documentation (#57).
Fixed
- Properly camelize keys in
deferredPropsmetadata whencamelize_propsis enabled.
2.5.1
Fixed
- Treat Igniter as an optional dependency in the
mix inertia.installtask definition. Previously, compilation would fail if Igniter was not installed.
2.5.0
Added
- Add
inertia_deep_merge/1function to support deep merging props on the client side (https://github.com/inertiajs/inertia/pull/2069) (#54). - Add Igniter installer task (#51).
2.4.0
Added
- Add
inertia_errors/1test helper to fetch Inertia errors (#43).
2.3.0
Added
- Add a
force_inertia_redirectplug function to instruct the client-side to always perform a full browser redirect when a redirect response is sent (#35).
Changed
- Define an
Inertia.Errorsprotocol with default implementations forEcto.ChangesetandMap.
2.2.0
Added
- Add
preserve_casehelper to prevent auto-camelization of specified prop keys. - Add
Inertia.Controller.inertia_response?/1helper to determine if a response is Inertia-rendered.
Fixed
- Ensure prop keys are compared in the proper casing (for partial reloads) when
camelize_propsis enabled. - Fix prop resolution for deferred/optional props.
2.1.0
Fixed
- Include new Inertia v2 attributes in the initial page object (
mergeProps,deferredProps,encryptHistory,clearHistory). - Mark internal component functions in
Inertia.HTMLas private.
2.0.0
Added
- Add support new Inertia.js v2.0.0.
- Add
encrypt_historyfunction to instruct the client-side to encrypt the history entry. - Add
clear_historyfunction to instruct the client-side to clear history. - Add
inertia_optionalfunction, to replace the now-deprecatedinertia_lazyfunction. - Add
inertia_mergefunction to instruct the client-side to merge the prop value with existing data. - Add
inertia_deferfunction to instruct the client-side to fetch the prop value immediately after initial page load.
- Add
- Add helpers for testing Inertia-based controller responses via the
Inertia.Testingmodule. - Add a
camelize_propsglobal config option and acamelize_propsfunction (to use on a per-request basis) to automatically convert prop keys from snake case to camel case. - Accept an
ssroption on therender_inertiafunction.
Changed
- Update Phoenix LiveView to v1.0.
- The errors serializer (for
Ecto.Changesetstructs) has been adjusted to better align with the behavior in the Laravel adapter in cases when there are multiple validation errors for a single field.
Old behavior for errors serializer
Previously, the serializer would include each error under a separate key, with a [0] index suffix, like this:
{
"name[0]": "is too long",
"name[1]": "is not real"
}While this retains maximal information about all the errors for a field, in practice it's difficult to target the right error records for display in the UI.
New behavior for errors serializer
Now, the serializer simply takes the first error message and returns it under the field name, without any added suffix:
{
"name": "is too long"
}Fixed
- Allow for external redirects from
PUT/PATCH/DELETErequests (#22) - Camelize prop names inside lists (e.g.
assign_prop(:items, [%{item_name: "..."}])).
Deprecated
- The
inertia_lazy/1function has been deprecated in favor ofinertia_optional/1
0.10.0
Bug Fixes
- Remove unsupported dot-notation in partial requests (related to inertiajs/inertia-laravel#641)
0.9.0
Bug Fixes
- Fix improper elimination of nested props when using only partials
0.8.0
Features
- Support unicode props (by using the
binaryflag on Node function calls)
0.7.0
Bug Fixes
- Fix exception when assigning structs as prop values (like
DateTime)
0.6.0
Bug Fixes
- Prevent overly greedy empty object elimination (#14)
0.5.0
- Assign errors via an
assign_errorshelper (#10) - Preserve assigned errors across redirects (#10)
- Set up external redirects properly for Inertia requests (#11)
- Pass CSRF tokens via cookies (#12)
- Forward flash contents across forced refreshes (#13)
- Automatically pass Phoenix flash data via the
flashprop
0.4.0
0.3.0
- Add
raise_on_ssr_failureconfiguration
0.2.0
- Add SSR support
- Add
<.inertia_head>component for rendering head elements provided by SSR
0.1.0
- Initial release