docs/props

Props

React

If you need more advanced React-integration, like server rendering, redux, or react-router, see shakacode/react_on_rails, react-rails, and webpacker-react.

If you’re not concerned with view helpers to pass props or server rendering, can do it yourself:

<%# views/layouts/application.html.erb %>

<%= content_tag :div,
  id: "hello-react",
  data: {
    message: 'Hello!',
    name: 'David'
}.to_json do %>
<% end %>
// app/javascript/packs/hello_react.js

const Hello = props => (
  <div>
    <img src="{clockIcon}" alt="clock">
    <h5>
      {props.message} {props.name}!
    </h5>
  </div>
)

// Render component with data
document.addEventListener('DOMContentLoaded', () =&gt; {
  const node = document.getElementById('hello-react')
  const data = JSON.parse(node.getAttribute('data'))

  ReactDOM.render(, node)
})

Vue

Add the data as attributes in the element you are going to use (or any other element for that matter).

&lt;%= content_tag :div,
  id: "hello-vue",
  data: {
    message: "Hello!",
    name: "David"
  }.to_json do %&gt;
&lt;% end %&gt;

This should produce the following HTML:

<div></div>

Now, modify your Vue app to expect the properties.

  <div>
    <p>{{test}}{{message}}{{name}}</p>
  </div>



  export default {
    // A child component needs to explicitly declare
    // the props it expects to receive using the props option
    // See https://vuejs.org/v2/guide/components.html#Props
    props: ["message","name"],
    data: function () {
      return {
        test: 'This will display: '
      }
    }
  }





document.addEventListener('DOMContentLoaded', () =&gt; {
  // Get the properties BEFORE the app is instantiated
  const node = document.getElementById('hello-vue')
  const props = JSON.parse(node.getAttribute('data'))

  // Render component with props
  new Vue({
    render: h =&gt; h(App, { props })
  }).$mount('#hello-vue');
})

You can follow same steps for Angular too.

Elm

Just like with other implementations, we’ll render our data inside a data
attribute:

&lt;%= content_tag :div,
  id: "hello-elm",
  data: {
    message: "Hello",
    name: "David"
  }.to_json do %&gt;
&lt;% end %&gt;

We parse the JSON data and pass it to Elm as flags:

import Elm from '../Main'

document.addEventListener('DOMContentLoaded', () =&gt; {
  const node = document.getElementById('hello-elm')
  const data = JSON.parse(node.getAttribute('data'))
  Elm.Main.embed(node, data)
})

Defining Flags as a type alias, we instruct Elm to demand flags message
and name of type String on initialization.

Using programWithFlags we bring all the pieces together:

module Main exposing (..)

import Html exposing (Html, programWithFlags, h1, text)
import Html.Attributes exposing (style)


-- MODEL


type alias Flags =
    { message : String
    , name : String
    }


type alias Model =
    { message : String
    , name : String
    }


type Msg
    = NoOp



-- INIT


init : Flags -&gt; ( Model, Cmd Msg )
init flags =
    let
        { message, name } =
            flags
    in
        ( Model message name, Cmd.none )



-- UPDATE


update : Msg -&gt; Model -&gt; ( Model, Cmd Msg )
update msg model =
    case msg of
        NoOp -&gt;
            ( model, Cmd.none )



-- SUBSCRIPTIONS


subscriptions : Model -&gt; Sub Msg
subscriptions model =
    Sub.none



-- VIEW


view : Model -&gt; Html Msg
view model =
    h1 [ style [ ( "display", "flex" ), ( "justify-content", "center" ) ] ]
        [ text (model.message ++ ", " ++ model.name ++ "!") ]



-- MAIN


main : Program Flags Model Msg
main =
    programWithFlags
        { view = view
        , init = init
        , update = update
        , subscriptions = subscriptions
        }