View Source Inertia.Controller (Inertia v2.3.0)
Controller functions for rendering Inertia.js responses.
Summary
Functions
Assigns errors to the Inertia page data. This helper accepts any data that
implements the Inertia.Errors
protocol. By default, this library implements
error serializers for Ecto.Changeset
and bare maps.
Assigns a prop value to the Inertia page data.
Enable (or disable) automatic conversion of prop keys from snake case (e.g.
inserted_at
), which is conventional in Elixir, to camel case (e.g.
insertedAt
), which is conventional in JavaScript.
Instuct the client-side to clear the history.
Instuct the client-side to encrypt history for this page.
Forces the Inertia.js client side to perform a redirect. This can be used as a plug or inline when building a response.
Marks a prop value as "always included", which means it will be included in the props on initial page load and subsequent partial loads (even when it's not explicitly requested).
Marks that a prop should fetched immediately after the page is loaded on the client-side.
Marks that a prop should be merged with existing data on the client-side.
Marks a prop value as optional, which means it will only get evaluated if explicitly requested in a partial reload.
Determines if a response has been rendered with Inertia.
Prevents auto-transformation of a prop key to camel-case (when
camelize_props
is enabled).
Renders an Inertia response.
Types
@opaque always()
@opaque defer()
@opaque merge()
@opaque optional()
@opaque preserved_prop_key()
@type prop_key() :: raw_prop_key() | preserved_prop_key()
@type render_opt() :: {:ssr, boolean()}
@type render_opts() :: [render_opt()]
Functions
@spec assign_errors(Plug.Conn.t(), data :: term()) :: Plug.Conn.t()
Assigns errors to the Inertia page data. This helper accepts any data that
implements the Inertia.Errors
protocol. By default, this library implements
error serializers for Ecto.Changeset
and bare maps.
If you are serializing your own errors maps, they should take the following shape:
%{
"name" => "Name is required",
"password" => "Password must be at least 5 characters",
"team.name" => "Team name is required",
}
When assigning a changeset, you may optionally pass a message-generating function
to use when traversing errors. See Ecto.Changeset.traverse_errors/2
for more information about the message function.
defp default_msg_func({msg, opts}) do
Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
end)
end
This default implementation performs a simple string replacement for error
message containing variables, like count
. For example, given the following
error:
{"should be at least %{count} characters", [count: 3, validation: :length, min: 3]}
The generated description would be "should be at least 3 characters". If you would
prefer to use the Gettext
module for pluralizing and localizing error messages, you
can override the message function:
conn
|> assign_errors(changeset, fn {msg, opts} ->
if count = opts[:count] do
Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
else
Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
end
end)
@spec assign_errors(Plug.Conn.t(), data :: term(), msg_func :: function()) :: Plug.Conn.t()
@spec assign_prop(Plug.Conn.t(), prop_key(), any()) :: Plug.Conn.t()
Assigns a prop value to the Inertia page data.
@spec camelize_props(Plug.Conn.t()) :: Plug.Conn.t()
Enable (or disable) automatic conversion of prop keys from snake case (e.g.
inserted_at
), which is conventional in Elixir, to camel case (e.g.
insertedAt
), which is conventional in JavaScript.
Examples
Using camelize_props
here will convert first_name
to firstName
in the
response props.
conn
|> assign_prop(:first_name, "Bob")
|> camelize_props()
|> render_inertia("Home")
You may also pass a boolean to the camelize_props
function (to override any
previously-set or globally-configured value):
conn
|> assign_prop(:first_name, "Bob")
|> camelize_props(false)
|> render_inertia("Home")
@spec camelize_props(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
@spec clear_history(Plug.Conn.t()) :: Plug.Conn.t()
Instuct the client-side to clear the history.
@spec clear_history(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
@spec encrypt_history(Plug.Conn.t()) :: Plug.Conn.t()
Instuct the client-side to encrypt history for this page.
@spec encrypt_history(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
@spec force_inertia_redirect(Plug.Conn.t(), opts :: keyword()) :: Plug.Conn.t()
Forces the Inertia.js client side to perform a redirect. This can be used as a plug or inline when building a response.
This plug modifies the response to be a 409 Conflict response and include the
destination URL in the x-inertia-location
header, which will cause the
Inertia client to perform a window.location = url
visit.
Note: we automatically convert regular external redirects (via the Phoenix
redirect
helper), but this function is useful if you need to force redirect
to a non-external route that is not handled by Inertia.
See https://inertiajs.com/redirects#external-redirects
Examples
conn
|> force_inertia_redirect()
|> redirect(to: "/non-inertia-powered-page")
Marks a prop value as "always included", which means it will be included in the props on initial page load and subsequent partial loads (even when it's not explicitly requested).
Marks that a prop should fetched immediately after the page is loaded on the client-side.
Marks that a prop should be merged with existing data on the client-side.
Marks a prop value as optional, which means it will only get evaluated if explicitly requested in a partial reload.
Optional props will only be included the when explicitly requested in a partial reload. If you want to include the prop on first visit, you'll want to use a bare anonymous function or named function reference instead.
conn
# ALWAYS included on first visit...
# OPTIONALLY included on partial reloads...
# ALWAYS evaluated...
|> assign_prop(:cheap_thing, cheap_thing())
# ALWAYS included on first visit...
# OPTIONALLY included on partial reloads...
# ONLY evaluated when needed...
|> assign_prop(:expensive_thing, fn -> calculate_thing() end)
|> assign_prop(:another_expensive_thing, &calculate_another_thing/0)
# NEVER included on first visit...
# OPTIONALLY included on partial reloads...
# ONLY evaluated when needed...
|> assign_prop(:super_expensive_thing, inertia_optional(fn -> calculate_thing() end))
@spec inertia_response?(Plug.Conn.t()) :: boolean()
Determines if a response has been rendered with Inertia.
@spec preserve_case(raw_prop_key()) :: preserved_prop_key()
Prevents auto-transformation of a prop key to camel-case (when
camelize_props
is enabled).
Example
conn
|> assign_prop(preserve_case(:this_will_not_be_camelized), "value")
|> assign_prop(:this_will_be_camelized, "another_value")
|> camelize_props()
|> render_inertia("Home")
You can also use this helper inside of nested props:
conn
|> assign_prop(:user, %{
preserve_case(:this_will_not_be_camelized) => "value",
this_will_be_camelized: "another_value"
})
|> camelize_props()
|> render_inertia("Home")
@spec render_inertia(Plug.Conn.t(), component :: String.t()) :: Plug.Conn.t()
Renders an Inertia response.
Options
ssr
: whether to server-side render the response (see the docs on "Server-side rendering" in the README for more information on setting this up). Defaults to the globally-configured value, orfalse
if no global config is specified.
Examples
conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage")
You may pass additional props as map for the third argument:
conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", %{name: "Bob"})
You may also pass options for the last positional argument:
conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", ssr: true)
conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", %{name: "Bob"}, ssr: true)
@spec render_inertia( Plug.Conn.t(), component :: String.t(), inline_props_or_opts :: map() | render_opts() ) :: Plug.Conn.t()
@spec render_inertia( Plug.Conn.t(), component :: String.t(), props :: map(), opts :: render_opts() ) :: Plug.Conn.t()