Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guide/asset-versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ One common challenge when building single-page apps is refreshing site assets wh

## Configuration

To enable automatic asset refreshing, you need to tell Inertia the current version of your assets. This can be any arbitrary string (letters, numbers, or a file hash), as long as it changes when your assets have been updated.
To enable automatic asset refreshing, you need to tell Inertia the current version of your assets using the `InertiaRails.configure` method and setting the `config.version` property. This can be any arbitrary string (letters, numbers, or a file hash), as long as it changes when your assets have been updated.

```ruby
InertiaRails.configure do |config|
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/client-side-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ npm install @inertiajs/svelte svelte

## Initialize the Inertia app

Next, update your main JavaScript file to boot your Inertia app. To accomplish this, we'll initialize the client-side framework with the base Inertia component.
Next, update your main JavaScript file to boot your Inertia app. To accomplish this, we'll use the `createInertiaApp` function to initialize the client-side framework with the base Inertia component.

:::tabs key:frameworks
== Vue
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Inertia Rails can be configured globally or in a specific controller (and subcla

## Global Configuration

If using global configuration, we recommend you place the code inside an initializer:
Use the `InertiaRails.configure` method to set global configuration options. If using global configuration, we recommend you place the code inside an initializer:

```ruby
# config/initializers/inertia.rb
Expand All @@ -19,7 +19,7 @@ The default configuration can be found [here](https://github.com/inertiajs/inert

## Local Configuration

Use `inertia_config` in your controllers to override global settings:
The `inertia_config` method allows you to override global settings in specific controllers. Use this method in your controllers to customize configuration for specific parts of your application:

```ruby
class EventsController < ApplicationController
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/csrf-protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Inertia's Rails adapter automatically includes the proper CSRF token when making requests via Inertia or Axios. Therefore, **no additional configuration is required**.

However, if you need to handle CSRF protection manually, one approach is to include the CSRF token as a prop on every response. You can then use the token when making Inertia requests.
However, if you need to handle CSRF protection manually, one approach is to include the CSRF token as a prop on every response. You can then use the token when making Inertia requests with the `router.post` method.

:::tabs key:frameworks
== Vue
Expand Down Expand Up @@ -67,7 +67,7 @@ When a CSRF token mismatch occurs, Rails raises the `ActionController::InvalidAu

Obviously, this isn't a great user experience. A better way to handle these errors is to return a redirect back to the previous page, along with a flash message that the page expired. This will result in a valid Inertia response with the flash message available as a prop which you can then display to the user. Of course, you'll need to share your [flash messages](/guide/shared-data.md#flash-messages) with Inertia for this to work.

You may modify your application's exception handler to automatically redirect the user back to the page they were previously on while flashing a message to the session. To accomplish this, you may use the `rescue_from` method in your `ApplicationController`.
You may modify your application's exception handler to automatically redirect the user back to the page they were previously on while flashing a message to the session. To accomplish this, you may use the `rescue_from` method in your `ApplicationController` to handle the `ActionController::InvalidAuthenticityToken` exception.

```ruby
class ApplicationController < ActionController::Base
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/deferred-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Inertia's deferred props feature allows you to defer the loading of certain page

## Server side

To defer a prop, you can use the defer method when returning your response. This method receives a callback that returns the prop data. The callback will be executed in a separate request after the initial page render.
To defer a prop, you can use the `InertiaRails.defer` method when returning your response. This method receives a callback that returns the prop data. The callback will be executed in a separate request after the initial page render.

```ruby
class UsersController < ApplicationController
Expand All @@ -20,7 +20,7 @@ end

### Grouping requests

By default, all deferred props get fetched in one request after the initial page is rendered, but you can choose to fetch data in parallel by grouping props together.
By default, all deferred props get fetched in one request after the initial page is rendered, but you can choose to fetch data in parallel by grouping props together using the `group` option with the `InertiaRails.defer` method.

```ruby
class UsersController < ApplicationController
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ For a full discussion on handling and displaying [validation](/guide/validation.

## Form helper

Since working with forms is so common, Inertia includes a form helper designed to help reduce the amount of boilerplate code needed for handling typical form submissions.
Since working with forms is so common, Inertia includes a form helper designed to help reduce the amount of boilerplate code needed for handling typical form submissions. The `useForm` method provides a convenient way to manage form state, validation, and submission.

:::tabs key:frameworks
== Vue
Expand Down
35 changes: 32 additions & 3 deletions docs/guide/history-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Imagine a scenario where your user is authenticated, browses privileged informat

When you instruct Inertia to encrypt your app's history, it uses the browser's built-in [`crypto` api](https://developer.mozilla.org/en-US/docs/Web/API/Crypto) to encrypt the current page's data before pushing it to the history state. We store the corresponding key in the browser's session storage. When the user navigates back to a page, we decrypt the data using the key stored in the session storage.

Once you instruct Inertia to clear your history state, we simply clear the existing key from session storage roll a new one. If we attempt to decrypt the history state with the new key, it will fail an Inertia will make a fresh request back to your server for the page data.
Once you instruct Inertia to clear your history state, we simply clear the existing key from session storage and roll out a new one. If we attempt to decrypt the history state with the new key, it will fail and Inertia will make a fresh request back to your server for the page data.

> [!NOTE]
> History encryption relies on `window.crypto.subtle` which is only available in secure environments (sites with SSL enabled).
Expand Down Expand Up @@ -47,12 +47,41 @@ end

## Clearing history

To clear the history state, you can pass the `clear_history` option to the `render` method:
To clear the history state on the server side, you can pass the `clear_history` option to the `render` method:

```ruby
render inertia: 'Dashboard', props: {}, clear_history: true
```

Once the response has rendered on the client, the encryption key will be rotated, rendering the previous history state unreadable.

You can also clear history on the client site by calling `router.clearHistory()`.
### Client-side clearing

You can also clear history directly on the client side by calling the `router.clearHistory()` method:

:::tabs key:frameworks
== Vue

```js
import { router } from '@inertiajs/vue3'

router.clearHistory()
```

== React

```js
import { router } from '@inertiajs/react'

router.clearHistory()
```

== Svelte 4|Svelte 5

```js
import { router } from '@inertiajs/svelte'

router.clearHistory()
```

:::
9 changes: 4 additions & 5 deletions docs/guide/manual-visits.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,14 @@ router.post('/users', {
== Svelte 4|Svelte 5

```js

```

import { router } from '@inertiajs/svelte'

router.post('/users', {
name: 'John Doe',
email: 'john.doe@example.com',
name: 'John Doe',
email: 'john.doe@example.com',
})
```

:::

## Custom headers
Expand Down
104 changes: 56 additions & 48 deletions docs/guide/responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,77 +23,51 @@ Within Rails applications, the `Event/Show` page would typically correspond to t
> [!WARNING]
> To ensure that pages load quickly, only return the minimum data required for the page. Also, be aware that **all data returned from the controllers will be visible client-side**, so be sure to omit sensitive information.

### Using instance variables as props
### Automatically determine component name

Inertia enables the automatic passing of instance variables as props. This can be achieved by invoking the `use_inertia_instance_props` function in a controller or in a base controller from which other controllers inherit.
You can pass props without specifying a component name:

```ruby
class EventsController < ApplicationController
use_inertia_instance_props

def index
@events = Event.all

render inertia: 'Events/Index'
class UsersController < ApplicationController
def show
render inertia: { user: @user } # Will render '../users/show.jsx|vue|svelte'
end
end
```

This action automatically passes the `@events` instance variable as the `events` prop to the `Events/Index` page component.

> [!NOTE]
> Manually providing any props for a response disables the instance props feature for that specific response.

> [!NOTE]
> Instance props are only included if they are defined **after** the `use_inertia_instance_props` call, hence the order of `before_action` callbacks is crucial.

### Automatically determine component name

Rails conventions can be used to automatically render the correct page component by invoking `render inertia: true`:
If the default component path doesn't match your convention, you can define a custom resolution method via the `component_path_resolver` config value. The value should be callable and will receive the path and action parameters, returning a string component path.

```ruby
class EventsController < ApplicationController
use_inertia_instance_props

def index
@events = Event.all

render inertia: true
inertia_config(
component_path_resolver: ->(path:, action:) do
"Storefront/#{path.camelize}/#{action.camelize}"
end
end
)
```

This renders the `app/frontend/pages/events/index.(jsx|vue|svelte)` page component and passes the `@events` instance variable as the `events` prop.

Setting the `default_render` configuration value to `true` establishes this as the default behavior:
### Using instance variables as props

```ruby
InertiaRails.configure do |config|
config.default_render = true
end
```
Inertia enables the automatic passing of instance variables as props. This can be achieved by invoking the `use_inertia_instance_props` function in a controller or in a base controller from which other controllers inherit.

```ruby
class EventsController < ApplicationController
use_inertia_instance_props

def index
@events = Event.all

render inertia: 'Events/Index'
end
end
```

With this configuration, the `app/frontend/pages/events/index.(jsx|vue|svelte)` page component is rendered automatically, passing the `@events` instance variable as the `events` prop.
This action automatically passes the `@events` instance variable as the `events` prop to the `Events/Index` page component.

If the default component path doesn't match your convention, you can define a custom resolution method via the `component_path_resolver` config value. The value should be callable and will receive the path and action parameters, returning a string component path.
> [!NOTE]
> Manually providing any props for a response disables the instance props feature for that specific response.

```ruby
inertia_config(
component_path_resolver: ->(path:, action:) do
"Storefront/#{path.camelize}/#{action.camelize}"
end
)
```
> [!NOTE]
> Instance props are only included if they are defined **after** the `use_inertia_instance_props` call, hence the order of `before_action` callbacks is crucial.

## Root template data

Expand Down Expand Up @@ -139,7 +113,7 @@ Inertia Rails provides a number of generators to help you get started with Inert

### Scaffold generator

To create a resource with Inertia responses, execute the following command in the terminal:
Use the `inertia:scaffold` generator to create a resource with Inertia responses. Execute the following command in the terminal:

```bash
bin/rails generate inertia:scaffold ModelName field1:type field2:type
Expand Down Expand Up @@ -185,7 +159,7 @@ Inertia Rails tries to detect the presence of Tailwind CSS in the application an

### Controller generator

To create a controller with an Inertia response, execute the following command in the terminal:
Use the `inertia:controller` generator to create a controller with an Inertia response. Execute the following command in the terminal:

```bash
bin/rails generate inertia:controller ControllerName action1 action2
Expand All @@ -211,7 +185,7 @@ $ bin/rails generate inertia:controller pages welcome next_steps

### Customizing the generator templates

Rails generators allow templates customization. For example, to customize the controller generator view template, create a file `lib/templates/inertia_templates/controller/react/view.jsx.tt`:
Rails generators allow templates customization. You can create custom template files in your application to override the default templates used by the generators. For example, to customize the controller generator view template for React, create a file at the path `lib/templates/inertia_templates/controller/react/view.jsx.tt`:

```jsx
export default function <%= @action.camelize %>() {
Expand All @@ -236,3 +210,37 @@ You can find the default templates in the gem's source code:
To enable client-side history navigation, all Inertia server responses are stored in the browser's history state. However, keep in mind that some browsers impose a size limit on how much data can be saved within the history state.

For example, [Firefox](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) has a size limit of 16 MiB and throws a `NS_ERROR_ILLEGAL_VALUE` error if you exceed this limit. Typically, this is much more data than you'll ever practically need when building applications.

## Detecting Inertia Requests

Controllers can determine if a request was made via Inertia:

```ruby
def some_action
if request.inertia?
# This is an Inertia request
end

if request.inertia_partial?
# This is a partial Inertia request
end
end
```

## Inertia responses and `respond_to`

Inertia responses always operate as a `:html` response type. This means that you can use the `respond_to` method to handle JSON requests differently, while still returning Inertia responses:

```ruby
def some_action
respond_to do |format|
format.html do
render inertia: 'Some/Component', props: { data: 'value' }
end

format.json do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

render json: { message: 'This is a JSON response' }
end
end
end
```
20 changes: 19 additions & 1 deletion docs/guide/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,25 @@ When using Inertia, all of your application's routes are defined server-side. Th
If you have a page that doesn't need a corresponding controller method, like an "FAQ" or "about" page, you can route directly to a component via the `inertia` method.

```ruby
inertia 'about' => 'AboutComponent'
# In config/routes.rb
Rails.application.routes.draw do
# Basic usage - maps 'dashboard' URL to 'Dashboard' component
inertia 'dashboard' => 'Dashboard'

# Using a symbol - infers component name from route
inertia :settings

# Within namespaces and scopes
namespace :admin do
inertia 'dashboard' => 'Admin/Dashboard'
end

# Within resource definitions
resources :users do
inertia :activity, on: :member
inertia :statistics, on: :collection
end
end
```

## Generating URLs
Expand Down
17 changes: 17 additions & 0 deletions docs/guide/shared-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ class EventsController < ApplicationController
end
```

### Inheritance and Shared Data

Shared data defined in parent controllers is automatically inherited by child controllers. Child controllers can also override or add to the shared data:

```ruby
# Parent controller
class ApplicationController < ActionController::Base
inertia_share app_name: 'My App', version: '1.0'
end

# Child controller
class UsersController < ApplicationController
# Inherits app_name and version, adds/overrides auth
inertia_share auth: -> { { user: current_user } }
end
```

### Conditional Sharing

You can control when data is shared using Rails-style controller filters. The `inertia_share` method supports these filter options:
Expand Down
2 changes: 2 additions & 0 deletions docs/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ end

### Assertions

Inertia Rails provides several RSpec matchers for testing Inertia responses. You can use methods like `expect_inertia`, `render_component`, `have_exact_props`, `include_props`, `have_exact_view_data`, and `include_view_data` to test your Inertia responses.

```ruby
# spec/requests/events_spec.rb
RSpec.describe '/events', inertia: true do
Expand Down