Skip to content

Conversation

kieraneglin
Copy link
Contributor

Resolves #247

Let me know what you think!

Comment on lines +47 to +72
### `prop_transformer`

**Default**: `->(props:) { props }`

Use `prop_transformer` to apply a transformation to your props before they're sent to the view. One use-case this enables is to work with `snake_case` props within Rails while working with `camelCase` in your view:

```ruby
inertia_config(
prop_transformer: lambda do |props:|
props.deep_transform_keys { |key| key.to_s.camelize(:lower) }
end
)
```

> [!NOTE]
> This controls the props provided by Inertia Rails but does not concern itself with props coming _into_ Rails. You may want to add a global `before_action` to `ApplicationController`:

```ruby
before_action :underscore_params

# ...

def underscore_params
params.deep_transform_keys! { |key| key.to_s.underscore }
end
```
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This probably needs work. Open to suggestions!

Copy link
Contributor

Choose a reason for hiding this comment

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

I would drop this additional section about input props tbh, this configuration option is not only about casing, so it looks misplaced to me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see where you're coming from, but I think it's very likely that prop casing is the principal usage of this feature. I can try adjusting the wording to be a little more generic but it makes sense to me to highlight the transformation isn't bidirectional

Comment on lines 93 to 99
merge_props(shared_data, props)
# This performs the internal work of hydrating/filtering props
.then { |props| deep_transform_props(props) }
# Then we apply the user-defined prop transformer
.then { |props| configuration.prop_transformer(props: props) }
# Then we add meta tags after everything since they must not be transformed
.tap { |props| props[:_inertia_meta] = meta_tags if meta_tags.present? }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This order ensures that any current or future internal props (like _inertia_meta) are untouched by the user-provided transformer. As long as they're added later in the chain than the call to prop_transformer, they're good to go

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks great. Super clean

@@ -0,0 +1,32 @@
# frozen_string_literal: true

class InertiaPropTransformerController < ApplicationController
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was kind of winging it with this. Open to feedback!

Copy link
Collaborator

@bknoles bknoles left a comment

Choose a reason for hiding this comment

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

This looks good to me! I'll wait to merge it until right before I release since the docs updates will build to the docs site immediately

@skryukov
Copy link
Contributor

@bknoles we can add @available_since rails=master macro to the docs and merge it right away, that was my intention when adding those labels

@bknoles bknoles merged commit 04b8f90 into inertiajs:master Aug 29, 2025
19 checks passed
@kieraneglin kieraneglin deleted the ke/prop-transformer branch September 2, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Suggestion] Add support for custom prop transformers
3 participants