Module: Isorun::AppHelper

Defined in:
app/helpers/isorun/app_helper.rb

Instance Method Summary collapse

Instance Method Details

#isorun_app(id, options = nil, ctx: {}) ⇒ String

The isorun_app helper is the most convenient way to server-side render a JavaScript application, including state extraction and automatic rehydration. The helper tries to render the application and will also inject the client-side code immediately after the rendered result.

Examples:

Renders a JavaScript application

<html>
<body>
  <%= isorun_app("my_app") %>
</body>
</html>

Parameters:

  • id (String)

    An ID representing both, the asset bundle, and by convention, the target node (e.g. <div id="my_app">)

  • options (Hash) (defaults to: nil)

    All valid tag options can also passed as options to this method

  • ctx (Hash, nil) (defaults to: {})

    Pass variables to render context

Returns:

  • (String)

See Also:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'app/helpers/isorun/app_helper.rb', line 24

def isorun_app(id, options = nil, ctx: {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  ActiveSupport::Notifications.instrument "start.render.isorun", { ts: Time.current }

  module_path = Isorun.config.module_resolver.call(id)

  ssr_html = Isorun::Context.create(receiver: Isorun.config.receiver) do |context|
    render_context = { environment: Rails.env.to_s }.merge(ctx)
    render_function = context.import.from(module_path)

    if render_function.blank?
      Rails.logger.warn("[ISORUN] the requested app does not exist or " \
                        "does not have a server entrypoint. Please " \
                        "check if an asset with filename " + "
                           `#{id}-server.js` exists.")
      return ""
    end

    html = render_function.call(render_context)

    ActiveSupport::Notifications.instrument "finish.render.isorun", { ts: Time.current }
    ActiveSupport::Notifications.instrument "stats.isorun", Isorun.stats

    html
  end

  html = if ssr_html.present?
           options ||= {}
           options[:id] = id

           tag.div(**options) do
             ssr_html.html_safe # rubocop:disable Rails/OutputSafety
           end
         else
           Rails.logger.warn("[ISORUN] The server-side rendered result is empty.")
           ""
         end

  html += "\n"
  html += javascript_include_tag(id, defer: true)
  html.html_safe # rubocop:disable Rails/OutputSafety
end