render_async 2.1.0 β†’ 2.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,31 +1,70 @@
1
- [![Build Status](https://semaphoreci.com/api/v1/renderedtext/render_async/branches/master/shields_badge.svg)](https://semaphoreci.com/renderedtext/render_async)
2
- [![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors)
3
- [![Gem Version](https://badge.fury.io/rb/render_async.svg)](https://badge.fury.io/rb/render_async)
4
- [![Code Climate](https://codeclimate.com/github/renderedtext/render_async/badges/gpa.svg)](https://codeclimate.com/github/renderedtext/render_async)
5
- [![Test Coverage](https://codeclimate.com/github/renderedtext/render_async/badges/coverage.svg)](https://codeclimate.com/github/renderedtext/render_async/coverage)
6
- [![Help Contribute to Open Source](https://www.codetriage.com/renderedtext/render_async/badges/users.svg)](https://www.codetriage.com/renderedtext/render_async)
7
-
8
- ![render_async](http://s2blog.wpengine.com/wp-content/uploads/assets/images/2017-06-08/speed-up-rendering-rails-pages-with-render-async.png)
9
-
10
- # render_async
11
-
12
- Speed up rendering Rails pages with this gem.
13
-
14
- `render_async` renders partials to your views **asynchronously**. This is done
15
- through adding JavaScript code that does AJAX request to your controller which
16
- then renders your partial into a Rails view.
17
-
18
- Workflow:
19
-
20
- 1. user visits a Rails page
21
- 2. AJAX request on the controller action
1
+ <p align="center">
2
+ <img src='http://s2blog.wpengine.com/wp-content/uploads/assets/images/2017-06-08/speed-up-rendering-rails-pages-with-render-async.png' alt='render_async' />
3
+
4
+ <h1 align="center">πŸ‘‹ Welcome to render_async</h1>
5
+
6
+ <h3 align="center">Let's make your Rails pages fast again :racehorse:</h3>
7
+
8
+ <br />
9
+
10
+ <p align="center">
11
+ <a href="https://www.paypal.me/nikolalsvk/10" target="_blank">
12
+ <img src="https://img.shields.io/badge/$-support-green.svg" alt="Donate" />
13
+ </a>
14
+ <a href="https://rubygems.org/gems/render_async" target="_blank">
15
+ <img src="https://img.shields.io/gem/dt/render_async" alt="Downloads" />
16
+ </a>
17
+ <a href="#contributors" target="_blank">
18
+ <img src="https://img.shields.io/github/all-contributors/renderedtext/render_async" alt="All contributors" />
19
+ </a>
20
+ <a href="https://badge.fury.io/rb/render_async" target="_blank">
21
+ <img src="https://badge.fury.io/rb/render_async.svg" alt="Gem Version" />
22
+ </a>
23
+ <br />
24
+ <a href="https://discord.gg/SPfbeRm" target="_blank">
25
+ <img src="https://img.shields.io/discord/738783603214909521" alt="Discord Server" />
26
+ </a>
27
+ <a href="https://semaphoreci.com/renderedtext/render_async" target="_blank">
28
+ <img src="https://semaphoreci.com/api/v1/renderedtext/render_async/branches/master/shields_badge.svg" alt="Build Status" />
29
+ </a>
30
+ <a href="https://codeclimate.com/github/renderedtext/render_async" target="_blank">
31
+ <img src="https://img.shields.io/codeclimate/maintainability/renderedtext/render_async" alt="Code Climate Maintainablity" />
32
+ </a>
33
+ <a href="https://codeclimate.com/github/renderedtext/render_async/coverage" target="_blank">
34
+ <img src="https://img.shields.io/codeclimate/coverage/renderedtext/render_async" alt="Test Coverage" />
35
+ </a>
36
+ <a href="https://github.com/renderedtext/render_async/blob/master/LICENSE" target="_blank">
37
+ <img src="https://img.shields.io/github/license/renderedtext/render_async" alt="License" />
38
+ </a>
39
+ <a href="https://www.codetriage.com/renderedtext/render_async" target="_blank">
40
+ <img src="https://www.codetriage.com/renderedtext/render_async/badges/users.svg" alt="Help Contribute to Open Source" />
41
+ </a>
42
+ </p>
43
+ </p>
44
+
45
+ ### `render_async` is here to make your pages show faster to users.
46
+
47
+ Pages become faster seamlessly by rendering partials to your views.
48
+
49
+ Partials render **asynchronously** and let users see your page **faster**
50
+ than using regular rendering.
51
+
52
+ It works with Rails and its tools out of the box.
53
+
54
+ :sparkles: A quick overview of how `render_async` does its magic:
55
+
56
+ 1. user visits a page
57
+ 2. `render_async` makes an AJAX request on the controller action
22
58
  3. controller renders a partial
23
- 4. partials renders in the place where you put `render_async` helper
59
+ 4. partial renders in the place where you put `render_async` view helper
24
60
 
25
- JavaScript is injected into `<%= content_for :render_async %>` so you choose
61
+ JavaScript is injected straight into `<%= content_for :render_async %>` so you choose
26
62
  where to put it.
27
63
 
28
- ## Installation
64
+ :mega: P.S. Join our [Discord channel](https://discord.gg/SPfbeRm) for help and discussion, and let's make `render_async` even better!
65
+
66
+ ## :package: Installation
67
+
29
68
  Add this line to your application's Gemfile:
30
69
 
31
70
  ```ruby
@@ -36,14 +75,14 @@ And then execute:
36
75
 
37
76
  $ bundle install
38
77
 
39
- ## Usage
78
+ ## :hammer: Usage
40
79
 
41
80
  1. Include `render_async` view helper somewhere in your views (e.g. `app/views/comments/show.html.erb`):
42
81
  ```erb
43
82
  <%= render_async comment_stats_path %>
44
83
  ```
45
84
 
46
- 2. Then create a route that will `config/routes.rb`:
85
+ 2. Then create a route for it `config/routes.rb`:
47
86
  ```ruby
48
87
  get :comment_stats, controller: :comments
49
88
  ```
@@ -69,7 +108,7 @@ And then execute:
69
108
  <%= content_for :render_async %>
70
109
  ```
71
110
 
72
- ## Advanced usage
111
+ ## :hammer_and_wrench: Advanced usage
73
112
 
74
113
  Advanced usage includes information on different options, such as:
75
114
 
@@ -79,15 +118,23 @@ Advanced usage includes information on different options, such as:
79
118
  - [Passing in an HTML element name](#passing-in-an-html-element-name)
80
119
  - [Passing in a placeholder](#passing-in-a-placeholder)
81
120
  - [Passing in an event name](#passing-in-an-event-name)
121
+ - [Using default events](#using-default-events)
122
+ - [Refreshing the partial](#refreshing-the-partial)
82
123
  - [Retry on failure](#retry-on-failure)
124
+ - [Retry after some time](#retry-after-some-time)
125
+ - [Toggle event](#toggle-event)
126
+ - [Control polling with a toggle](#control-polling-with-a-toggle)
83
127
  - [Polling](#polling)
128
+ - [Controlled polling](#controlled-polling)
84
129
  - [Handling errors](#handling-errors)
85
130
  - [Caching](#caching)
86
131
  - [Doing non-GET requests](#doing-non-get-requests)
87
132
  - [Using with Turbolinks](#using-with-turbolinks)
133
+ - [Using with Turbo](#using-with-turbo)
88
134
  - [Using with respond_to and JS format](#using-with-respond_to-and-js-format)
89
- - [Nested Async Renders](#nested-async-renders)
90
- - [Configuration](#configuration)
135
+ - [Nested async renders](#nested-async-renders)
136
+ - [Customizing the content_for name](#customizing-the-content_for-name)
137
+ - [Configuration options](#configuration-options)
91
138
 
92
139
  ### Passing in a container ID
93
140
 
@@ -128,27 +175,32 @@ Rendered code in the view:
128
175
 
129
176
  ### Passing in HTML options
130
177
 
131
- `render_async` can accept `html_options` argument.
178
+ `render_async` can accept `html_options` as a hash.
132
179
  `html_options` is an optional hash that gets passed to a Rails'
133
180
  `javascript_tag`, to drop HTML tags into the `script` element.
134
181
 
135
- Example of utilizing `html_options` with a `nonce`:
182
+ Example of utilizing `html_options` with a [nonce](https://edgeguides.rubyonrails.org/security.html#content-security-policy):
183
+
136
184
  ```erb
137
- <%= render_async users_path, nonce: 'lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=' %>
185
+ <%= render_async users_path, html_options: { nonce: true } %>
138
186
  ```
139
187
 
140
188
  Rendered code in the view:
141
189
  ```html
142
- <div id="render_async_18b8a6cd161499117471">
143
- </div>
144
-
145
- <script nonce="lWaaV6eYicpt+oyOfcShYINsz0b70iR+Q1mohZqNaag=">
190
+ <script nonce="2x012CYGxKgM8qAApxRHxA==">
146
191
  //<![CDATA[
147
192
  ...
148
193
  //]]>
149
194
  </script>
195
+
196
+ ...
197
+
198
+ <div id="render_async_18b8a6cd161499117471" class="">
199
+ </div>
150
200
  ```
151
201
 
202
+ > :bulb: You can enable `nonce` to be set everywhere by using [configuration option](#configuration-options) render_async provides.
203
+
152
204
  ### Passing in an HTML element name
153
205
 
154
206
  `render_async` can take in an HTML element name, allowing you to control
@@ -206,6 +258,9 @@ event after it's done with fetching and rendering request content to HTML.
206
258
  This can be useful to have if you want to add some JavaScript functionality
207
259
  after your partial is loaded through `render_async`.
208
260
 
261
+ You can also access the associated container (DOM node) in the event object
262
+ that gets emitted.
263
+
209
264
  Example of passing it to `render_async`:
210
265
  ```erb
211
266
  <%= render_async users_path, event_name: "users-loaded" %>
@@ -225,15 +280,77 @@ Rendered code in view:
225
280
  </script>
226
281
  ```
227
282
 
228
- Then, in your JS, you could do something like this:
283
+ Then, in your JavaScript code, you could do something like this:
229
284
  ```javascript
230
- document.addEventListener("users-loaded", function() {
231
- console.log("Users have loaded!");
285
+ document.addEventListener("users-loaded", function(event) {
286
+ console.log("Users have loaded!", event.container); // Access the container which loaded the users
232
287
  });
233
288
  ```
234
289
 
235
- NOTE: Dispatching events is also supported for older browsers that don't
236
- support Event constructor.
290
+ > :bulb: Dispatching events is also supported for older browsers that don't support Event constructor.
291
+
292
+ ### Using default events
293
+
294
+ `render_async` will fire the event `render_async_load` when an async partial
295
+ has loaded and rendered on the page.
296
+
297
+ In case there is an error, the event `render_async_error` will fire instead.
298
+
299
+ This event will fire for all `render_async` partials on the page. For every
300
+ event, the associated container (DOM node) will be passed along.
301
+
302
+ This can be useful to apply JavaScript to content loaded after the page is
303
+ ready.
304
+
305
+ Example of using events:
306
+
307
+ ```js
308
+ // Vanilla javascript
309
+ document.addEventListener('render_async_load', function(event) {
310
+ console.log('Async partial loaded in this container:', event.container);
311
+ });
312
+ document.addEventListener('render_async_error', function(event) {
313
+ console.log('Async partial could not load in this container:', event.container);
314
+ });
315
+
316
+ // with jQuery
317
+ $(document).on('render_async_load', function(event) {
318
+ console.log('Async partial loaded in this container:', event.container);
319
+ });
320
+ $(document).on('render_async_error', function(event) {
321
+ console.log('Async partial could not load in this container:', event.container);
322
+ });
323
+ ```
324
+
325
+ ### Refreshing the partial
326
+
327
+ `render_async` lets you refresh (reload) the partial by letting you dispatch
328
+ the 'refresh' event on the `render_async`'s container. An example:
329
+
330
+ ```erb
331
+ <%= render_async comments_path,
332
+ container_id: 'refresh-me',
333
+ replace_container: false %>
334
+
335
+ <button id="refresh-button">Refresh comments</button>
336
+
337
+ <script>
338
+ var button = document.getElementById('refresh-button')
339
+ var container = document.getElementById('refresh-me');
340
+
341
+ button.addEventListener('click', function() {
342
+ var event = new Event('refresh');
343
+
344
+ // Dispatch 'refresh' on the render_async container
345
+ container.dispatchEvent(event)
346
+ })
347
+ </script>
348
+ ```
349
+
350
+ If you follow the example above, when you click "Refresh comments" button,
351
+ `render_async` will trigger again and reload the `comments_path`.
352
+
353
+ > :bulb: Note that you need to pass `replace_container: false` so you can later dispatch an event on that container.
237
354
 
238
355
  ### Retry on failure
239
356
 
@@ -245,17 +362,120 @@ this:
245
362
  <%= render_async users_path, retry_count: 5, error_message: "Couldn't fetch it" %>
246
363
  ```
247
364
 
248
- Now render_async will retry `users_path` for 5 times. If it succedes in
365
+ Now render_async will retry `users_path` for 5 times. If it succeeds in
249
366
  between, it will stop with dispatching requests. If it fails after 5 times,
250
367
  it will show an [error message](#handling-errors) which you need to specify.
251
368
 
252
369
  This can show useful when you know your requests often fail, and you don't want
253
370
  to refresh the whole page just to retry them.
254
371
 
372
+ #### Retry after some time
373
+
374
+ If you want to retry requests but with some delay in between the calls, you can
375
+ pass a `retry_delay` option together with `retry_count` like so:
376
+
377
+ ```erb
378
+ <%= render_async users_path,
379
+ retry_count: 5,
380
+ retry_delay: 2000 %>
381
+ ```
382
+
383
+ This will make `render_async` wait for 2 seconds before retrying after each
384
+ failure. In the end, if the request is still failing after 5th time, it will
385
+ dispatch a [default error event](#using-default-events).
386
+
387
+ > :candy: If you are catching an event after an error, you can get `retryCount` from
388
+ the event. `retryCount` will have the number of retries it took before the event was dispatched.
389
+
390
+ Here is an example on how to get `retryCount`:
391
+
392
+ ```erb
393
+ <%= render_async users_path,
394
+ retry_count: 5,
395
+ retry_delay: 2000,
396
+ error_event_name: 'it-failed-badly' %>
397
+
398
+ <script>
399
+ document.addEventListener('it-failed-badly', function(event) {
400
+ console.log("Request failed after " + event.retryCount + " tries!")
401
+ });
402
+ </script>
403
+ ```
404
+
405
+ If you need to pass retry count to the backend, you can pass `retry_count_header` in `render_async`'s options:
406
+
407
+ ```erb
408
+ <%= render_async users_path,
409
+ retry_count: 5,
410
+ retry_count_header: 'Retry-Count-Current' %>
411
+ ```
412
+
413
+ And then in controller you can read the value from request headers.
414
+
415
+ ```
416
+ request.headers['Retry-Count-Current']&.to_i
417
+ ```
418
+
419
+ ### Toggle event
420
+
421
+ You can trigger `render_async` loading by clicking or doing another event to a
422
+ certain HTML element. You can do this by passing in a selector and an event
423
+ name which will trigger `render_async`. If you don't specify an event name, the
424
+ default event that will trigger `render_async` will be 'click' event. You can
425
+ do this by doing the following:
426
+
427
+ ```erb
428
+ <a href='#' id='comments-button'>Load comments</a>
429
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } %>
430
+ ```
431
+
432
+ This will trigger `render_async` to load the `comments_path` when you click the `#comments-button` element.
433
+ If you want to remove an event once it's triggered, you can pass `once: true` in the toggle options.
434
+ The `once` option is false (`nil`) by default.
435
+
436
+ You can also pass in a placeholder before the `render_async` is triggered. That
437
+ way, the element that started `render_async` logic will be removed after the
438
+ request has been completed. You can achieve this behaviour with something like this:
439
+
440
+ ```erb
441
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click } do %>
442
+ <a href='#' id='comments-button'>Load comments</a>
443
+ <% end %>
444
+ ```
445
+
446
+ #### Control polling with a toggle
447
+
448
+ Also, you can mix interval and toggle features. This way, you can turn polling
449
+ on, and off by clicking the "Load comments" button. In order to do this, you need to
450
+ pass `toggle` and `interval` arguments to `render_async` call like this:
451
+
452
+ ```erb
453
+ <a href='#' id='comments-button'>Load comments</a>
454
+ <%= render_async comments_path, toggle: { selector: '#comments-button', event: :click }, interval: 2000 %>
455
+ ```
456
+
457
+ If you want `render_async` to render the request on load, you can pass `start:
458
+ true`. Passing the `start` option inside the `toggle` hash will trigger
459
+ `render_async` on page load. You can then toggle off polling by interacting
460
+ with the element you specified. An example:
461
+
462
+ ```erb
463
+ <a href='#' id='comments-button'>Toggle comments loading</a>
464
+ <%= render_async comments_path,
465
+ toggle: { selector: '#comments-button',
466
+ event: :click,
467
+ start: true },
468
+ interval: 2000 %>
469
+ ```
470
+
471
+ In the example above, the comments will load as soon as the page is rendered.
472
+ Then, you can stop polling for comments by clicking the "Toggle comments
473
+ loading" button.
474
+
255
475
  ### Polling
256
476
 
257
477
  You can call `render_async` with interval argument. This will make render_async
258
- call specified path at specified interval.
478
+ call specified path at the specified interval.
259
479
 
260
480
  By doing this:
261
481
  ```erb
@@ -265,15 +485,65 @@ You are telling `render_async` to fetch comments_path every 5 seconds.
265
485
 
266
486
  This can be handy if you want to enable polling for a specific URL.
267
487
 
268
- NOTE: By passing interval to `render_async`, initial container element
269
- will remain in HTML tree, it will not be replaced with request response.
270
- You can handle how that container element is rendered and its style by
271
- [passing in an HTML element name](#passing-in-an-html-element-name) and
272
- [HTML element class](#passing-in-a-container-class-name).
488
+ > :warning: By passing interval to `render_async`, the initial container element
489
+ > will remain in the HTML tree and it will not be replaced with request response.
490
+ > You can handle how that container element is rendered and its style by
491
+ > [passing in an HTML element name](#passing-in-an-html-element-name) and
492
+ > [HTML element class](#passing-in-a-container-class-name).
493
+
494
+ ### Controlled polling
495
+
496
+ You can controller `render_async` [polling](#polling) in 2 manners.
497
+ First one is pretty simple, and it involves using the [toggle](#toggle-event)
498
+ feature. To do this, you can follow instructions in the
499
+ [control polling with a toggle section](#control-polling-with-a-toggle).
500
+
501
+ The second option is more advanced and it involves emitting events to the `render_async`'s
502
+ container element. From your code, you can emit the following events:
503
+ - 'async-stop' - this will stop polling
504
+ - 'async-start' - this will start polling.
505
+
506
+ > :bulb: Please note that events need to be dispatched to a render_async container.
507
+
508
+ An example of how you can do this looks like this:
509
+
510
+ ```erb
511
+ <%= render_async wave_render_async_path,
512
+ container_id: 'controllable-interval', # set container_id so we can get it later easily
513
+ interval: 3000 %>
514
+
515
+ <button id='stop-polling'>Stop polling</button>
516
+ <button id='start-polling'>Start polling</button>
517
+
518
+ <script>
519
+ var container = document.getElementById('controllable-interval')
520
+ var stopPolling = document.getElementById('stop-polling')
521
+ var startPolling = document.getElementById('start-polling')
522
+
523
+ var triggerEventOnContainer = function(eventName) {
524
+ var event = new Event(eventName);
525
+
526
+ container.dispatchEvent(event)
527
+ }
528
+
529
+ stopPolling.addEventListener('click', function() {
530
+ container.innerHTML = '<p>Polling stopped</p>'
531
+ triggerEventOnContainer('async-stop')
532
+ })
533
+ startPolling.addEventListener('click', function() {
534
+ triggerEventOnContainer('async-start')
535
+ })
536
+ </script>
537
+ ```
538
+
539
+ We are rendering two buttons - "Stop polling" and "Start polling". Then, we
540
+ attach an event listener to catch any clicking on the buttons. When the buttons
541
+ are clicked, we either stop the polling or start the polling, depending on which
542
+ button a user clicks.
273
543
 
274
544
  ### Handling errors
275
545
 
276
- `render_async` let's you handle errors by allowing you to pass in `error_message`
546
+ `render_async` lets you handle errors by allowing you to pass in `error_message`
277
547
  and `error_event_name`.
278
548
 
279
549
  - `error_message`
@@ -319,10 +589,10 @@ Then, in the partial (e.g. `app/views/comments/_comment_stats.html.erb`):
319
589
  <% end %>
320
590
  ```
321
591
 
322
- * The first time the page renders, it will make the AJAX call.
323
- * Any other times (until the cache expires), it will render from cache
592
+ - The first time the page renders, it will make the AJAX call.
593
+ - Any other times (until the cache expires), it will render from cache
324
594
  instantly, without making the AJAX call.
325
- * You can expire cache simply by passing `:expires_in` in your view where
595
+ - You can expire cache simply by passing `:expires_in` in your view where
326
596
  you cache the partial
327
597
 
328
598
  ### Doing non-GET requests
@@ -351,7 +621,7 @@ away from, and then back to, a page with a `render_async` call on it. This will
351
621
  likely show up as an empty div.
352
622
 
353
623
  If you're using Turbolinks 5 or higher, you can resolve this by setting Turbolinks
354
- configurtion of `render_async` to true:
624
+ configuration of `render_async` to true:
355
625
 
356
626
  ```rb
357
627
  RenderAsync.configure do |config|
@@ -360,19 +630,49 @@ end
360
630
  ```
361
631
 
362
632
  This way, you're not breaking Turbolinks flow of loading or reloading a page.
363
- It makes it more efficient that the next option that is suggested below.
633
+ It is more efficient than the next option below.
364
634
 
365
635
  Another option:
366
636
  If you want, you can tell Turbolinks to reload your `render_async` call as follows:
367
637
 
368
638
  ```erb
369
- <%= render_async events_path, 'data-turbolinks-track': 'reload' %>
639
+ <%= render_async events_path, html_options: { 'data-turbolinks-track': 'reload' } %>
370
640
  ```
371
641
 
372
642
  This will reload the whole page with Turbolinks.
373
643
 
374
- Make sure to put `<%= content_for :render_async %>` in your base view file in
375
- the `<head>` and not the `<body>`.
644
+ > :bulb: If Turbolinks is misbehaving in some way, make sure to put `<%= content_for :render_async %>` in your base view file in
645
+ the `<body>` and not the `<head>`.
646
+
647
+ ### Using with Turbo
648
+
649
+ On Turbo applications, you may experience caching issues when navigating
650
+ away from, and then back to, a page with a `render_async` call on it. This will
651
+ likely show up as an empty div.
652
+
653
+ If you're using Turbo, you can resolve this by setting Turbo
654
+ configuration of `render_async` to true:
655
+
656
+ ```rb
657
+ RenderAsync.configure do |config|
658
+ config.turbo = true # Enable this option if you are using Turbo
659
+ end
660
+ ```
661
+
662
+ This way, you're not breaking Turbos flow of loading or reloading a page.
663
+ It is more efficient than the next option below.
664
+
665
+ Another option:
666
+ If you want, you can tell Turbo to reload your `render_async` call as follows:
667
+
668
+ ```erb
669
+ <%= render_async events_path, html_options: { 'data-turbo-track': 'reload' } %>
670
+ ```
671
+
672
+ This will reload the whole page with Turbo.
673
+
674
+ > :bulb: If Turbo is misbehaving in some way, make sure to put `<%= content_for :render_async %>` in your base view file in
675
+ the `<body>` and not the `<head>`.
376
676
 
377
677
  ### Using with respond_to and JS format
378
678
 
@@ -391,7 +691,7 @@ def comment_stats
391
691
  end
392
692
  ```
393
693
 
394
- When you do this, Rails will sometime set the response's `Content-Type` header
694
+ When you do this, Rails will sometimes set the response's `Content-Type` header
395
695
  to `text/javascript`. This causes the partial not to be rendered in the HTML.
396
696
  This usually happens when there's browser caching.
397
697
 
@@ -402,7 +702,7 @@ render call:
402
702
  render partial: "comment_stats", content_type: 'text/html'
403
703
  ```
404
704
 
405
- ### Nested Async Renders
705
+ ### Nested async renders
406
706
 
407
707
  It is possible to nest async templates within other async templates. When doing
408
708
  so, another `content_for` is required to ensure the JavaScript needed to load
@@ -429,7 +729,20 @@ For example:
429
729
  <%= content_for :render_async %>
430
730
  ```
431
731
 
432
- ### Configuration
732
+ ### Customizing the content_for name
733
+
734
+ The `content_for` name may be customized by passing the `content_for_name`
735
+ option to `render_async`. This option is especially useful when doing [nested async
736
+ renders](#nested-async-renders) to better control the location of the injected JavaScript.
737
+
738
+ For example:
739
+ ```erb
740
+ <%= render_async comment_stats_path, content_for_name: :render_async_comment_stats %>
741
+
742
+ <%= content_for :render_async_comment_stats %>
743
+ ```
744
+
745
+ ### Configuration options
433
746
 
434
747
  `render_async` renders Vanilla JS (regular JavaScript, non-jQuery code)
435
748
  **by default** in order to fetch the request from the server.
@@ -439,10 +752,14 @@ so.
439
752
 
440
753
  You can configure it by doing the following anywhere before you call
441
754
  `render_async`:
755
+
442
756
  ```rb
443
757
  RenderAsync.configure do |config|
444
- config.jquery = true # This will render jQuery code, and skip Vanilla JS code
445
- config.turbolinks = false # Enable this option if you are using Turbolinks 5+
758
+ config.jquery = true # This will render jQuery code, and skip Vanilla JS code. The default value is false.
759
+ config.turbolinks = true # Enable this option if you are using Turbolinks 5+. The default value is false.
760
+ config.turbo = true # Enable this option if you are using Turbo. The default value is false.
761
+ config.replace_container = false # Set to false if you want to keep the placeholder div element from render_async. The default value is true.
762
+ config.nonces = true # Set to true if you want render_async's javascript_tag always to receive nonce: true. The default value is false.
446
763
  end
447
764
  ```
448
765
 
@@ -452,17 +769,34 @@ Also, you can do it like this:
452
769
  RenderAsync.configuration.jquery = true
453
770
  ```
454
771
 
455
- ## Development
772
+ Aside from configuring whether the gem relies on jQuery or VanillaJS, you can
773
+ configure other options:
774
+
775
+ - `turbolinks` option - If you are using Turbolinks 5+, you should enable this option since it supports Turbolinks way of loading data. The default value for this option is false.
776
+ - `turbo` option - If you are using Turbo, you should enable this option since it supports Turbo way of loading data. The default value for this option is false.
777
+ - `replace_container` option - If you want render_async to replace its container with the request response, turn this on. You can turn this on globally for all render_async calls, but if you use this option in a specific render_async call, it will override the global configuration. The default value is true.
778
+ - `nonces` - If you need to pass in `nonce: true` to the `javascript_tag` in your application, it might make sense for you to turn this on globally for all render_async calls. To read more about nonces, check out [Rails' official guide on security](https://edgeguides.rubyonrails.org/security.html). The default value is false.
779
+
780
+ ## :hammer_and_pick: Development
456
781
 
457
782
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
458
783
  `rake spec` to run the tests. You can also run `bin/console` for an interactive
459
- prompt that will allow you to experiment.
784
+ prompt that will allow you to experiment. To run integration tests, use
785
+ `bin/integration-tests`. For more information, check out [CONTRIBUTING](.github/CONTRIBUTING.md) file, please.
786
+
787
+ Got any questions or comments about development (or anything else)?
788
+ Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
789
+ and let's make `render_async` even better!
790
+
791
+ ## :pray: Contributing
460
792
 
461
- ## Contributing
793
+ Check out [CONTRIBUTING](.github/CONTRIBUTING.md) file, please.
462
794
 
463
- Bug reports and pull requests are welcome on GitHub at https://github.com/renderedtext/render_async.
795
+ Got any issues or difficulties?
796
+ Join [render_async's Discord channel](https://discord.gg/SPfbeRm)
797
+ and let's make `render_async` even better!
464
798
 
465
- ## License
799
+ ## :memo: License
466
800
 
467
801
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
468
802
 
@@ -472,10 +806,11 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
472
806
 
473
807
  <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
474
808
  <!-- prettier-ignore -->
475
- | [<img src="https://avatars2.githubusercontent.com/u/3028124?v=4" width="100px;"/><br /><sub><b>Nikola Đuza</b></sub>](http://nikoladjuza.me/)<br />[πŸ’¬](#question-nikolalsvk "Answering Questions") [πŸ’»](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Documentation") [πŸ‘€](#review-nikolalsvk "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/3866868?v=4" width="100px;"/><br /><sub><b>Colin</b></sub>](http://www.colinxfleming.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Documentation") [πŸ’‘](#example-colinxfleming "Examples") | [<img src="https://avatars2.githubusercontent.com/u/334273?v=4" width="100px;"/><br /><sub><b>Kasper Grubbe</b></sub>](http://kaspergrubbe.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=kaspergrubbe "Code") | [<img src="https://avatars2.githubusercontent.com/u/163584?v=4" width="100px;"/><br /><sub><b>Sai Ram Kunala</b></sub>](https://sairam.xyz/)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=sairam "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3065882?v=4" width="100px;"/><br /><sub><b>Josh Arnold</b></sub>](https://github.com/nightsurge)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=nightsurge "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=nightsurge "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/107798?v=4" width="100px;"/><br /><sub><b>Elad Shahar</b></sub>](https://eladshahar.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=SaladFork "Code") [πŸ’‘](#example-SaladFork "Examples") | [<img src="https://avatars3.githubusercontent.com/u/232392?v=4" width="100px;"/><br /><sub><b>Sasha</b></sub>](http://www.revzin.co.il)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Documentation") |
809
+ | [<img src="https://avatars2.githubusercontent.com/u/3028124?v=4" width="100px;"/><br /><sub><b>Nikola Đuza</b></sub>](https://nikolalsvk.github.io)<br />[πŸ’¬](#question-nikolalsvk "Answering Questions") [πŸ’»](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=nikolalsvk "Documentation") [πŸ‘€](#review-nikolalsvk "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/3866868?v=4" width="100px;"/><br /><sub><b>Colin</b></sub>](http://www.colinxfleming.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=colinxfleming "Documentation") [πŸ’‘](#example-colinxfleming "Examples") | [<img src="https://avatars2.githubusercontent.com/u/334273?v=4" width="100px;"/><br /><sub><b>Kasper Grubbe</b></sub>](http://kaspergrubbe.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=kaspergrubbe "Code") | [<img src="https://avatars2.githubusercontent.com/u/163584?v=4" width="100px;"/><br /><sub><b>Sai Ram Kunala</b></sub>](https://sairam.xyz/)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=sairam "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/3065882?v=4" width="100px;"/><br /><sub><b>Josh Arnold</b></sub>](https://github.com/nightsurge)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=nightsurge "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=nightsurge "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/107798?v=4" width="100px;"/><br /><sub><b>Elad Shahar</b></sub>](https://eladshahar.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=SaladFork "Code") [πŸ’‘](#example-SaladFork "Examples") | [<img src="https://avatars3.githubusercontent.com/u/232392?v=4" width="100px;"/><br /><sub><b>Sasha</b></sub>](http://www.revzin.co.il)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=sasharevzin "Documentation") |
476
810
  | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
477
- | [<img src="https://avatars3.githubusercontent.com/u/50223?v=4" width="100px;"/><br /><sub><b>Ernest Surudo</b></sub>](http://elsurudo.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=elsurudo "Code") | [<img src="https://avatars1.githubusercontent.com/u/334809?v=4" width="100px;"/><br /><sub><b>Kurtis Rainbolt-Greene</b></sub>](https://kurtis.rainbolt-greene.online)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=krainboltgreene "Code") | [<img src="https://avatars2.githubusercontent.com/u/59744?v=4" width="100px;"/><br /><sub><b>Richard Schneeman</b></sub>](https://www.schneems.com)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=schneems "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/75705?v=4" width="100px;"/><br /><sub><b>Richard Venneman</b></sub>](https://www.cityspotters.com)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=richardvenneman "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/381395?v=4" width="100px;"/><br /><sub><b>Filipe W. Lima</b></sub>](https://github.com/filipewl)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=filipewl "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/3135638?v=4" width="100px;"/><br /><sub><b>JesΓΊs Eduardo Clemens Chong</b></sub>](https://github.com/eclemens)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=eclemens "Code") | [<img src="https://avatars3.githubusercontent.com/u/1935686?v=4" width="100px;"/><br /><sub><b>RenΓ© Klačan</b></sub>](https://github.com/reneklacan)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=reneklacan "Code") |
478
- | [<img src="https://avatars1.githubusercontent.com/u/1313442?v=4" width="100px;"/><br /><sub><b>Gil Gomes</b></sub>](http://gilgomes.com.br)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=gil27 "Documentation") |
811
+ | [<img src="https://avatars3.githubusercontent.com/u/50223?v=4" width="100px;"/><br /><sub><b>Ernest Surudo</b></sub>](http://elsurudo.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=elsurudo "Code") | [<img src="https://avatars1.githubusercontent.com/u/334809?v=4" width="100px;"/><br /><sub><b>Kurtis Rainbolt-Greene</b></sub>](https://kurtis.rainbolt-greene.online)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=krainboltgreene "Code") | [<img src="https://avatars2.githubusercontent.com/u/59744?v=4" width="100px;"/><br /><sub><b>Richard Schneeman</b></sub>](https://www.schneems.com)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=schneems "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/75705?v=4" width="100px;"/><br /><sub><b>Richard Venneman</b></sub>](https://www.cityspotters.com)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=richardvenneman "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/381395?v=4" width="100px;"/><br /><sub><b>Filipe W. Lima</b></sub>](https://github.com/filipewl)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=filipewl "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/3135638?v=4" width="100px;"/><br /><sub><b>JesΓΊs Eduardo Clemens Chong</b></sub>](https://github.com/eclemens)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=eclemens "Code") | [<img src="https://avatars3.githubusercontent.com/u/1935686?v=4" width="100px;"/><br /><sub><b>RenΓ© Klačan</b></sub>](https://github.com/reneklacan)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=reneklacan "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=reneklacan "Documentation") |
812
+ | [<img src="https://avatars1.githubusercontent.com/u/1313442?v=4" width="100px;"/><br /><sub><b>Gil Gomes</b></sub>](http://gilgomes.com.br)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=gil27 "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/6081795?v=4" width="100px;"/><br /><sub><b>Khoa Nguyen</b></sub>](https://github.com/ThanhKhoaIT)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=ThanhKhoaIT "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/8645918?v=4" width="100px;"/><br /><sub><b>Preet Sethi</b></sub>](https://www.linkedin.com/in/preetsethila/)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=preetsethi "Code") | [<img src="https://avatars3.githubusercontent.com/u/11586335?v=4" width="100px;"/><br /><sub><b>fangxing</b></sub>](https://github.com/fffx)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=fffx "Code") | [<img src="https://avatars3.githubusercontent.com/u/1191418?v=4" width="100px;"/><br /><sub><b>Emmanuel Pire</b></sub>](http://blog.lipsumarium.com)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=lipsumar "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=lipsumar "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/615509?v=4" width="100px;"/><br /><sub><b>Maxim Geerinck</b></sub>](https://github.com/maximgeerinck)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=maximgeerinck "Code") | [<img src="https://avatars1.githubusercontent.com/u/251706?v=4" width="100px;"/><br /><sub><b>Don</b></sub>](https://github.com/vanboom)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=vanboom "Code") |
813
+ | [<img src="https://avatars0.githubusercontent.com/u/998682?v=4" width="100px;"/><br /><sub><b>villu164</b></sub>](https://github.com/villu164)<br />[πŸ“–](https://github.com/renderedtext/render_async/commits?author=villu164 "Documentation") | [<img src="https://avatars.githubusercontent.com/u/11203679?v=4" width="100px;"/><br /><sub><b>Mitchell Buckley</b></sub>](https://github.com/Mbuckley0)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=Mbuckley0 "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=Mbuckley0 "Documentation") | [<img src="https://avatars.githubusercontent.com/u/15371677?v=4" width="100px;"/><br /><sub><b>yhirano55</b></sub>](https://github.com/yhirano55)<br />[πŸ’»](https://github.com/renderedtext/render_async/commits?author=yhirano55 "Code") [πŸ“–](https://github.com/renderedtext/render_async/commits?author=yhirano55 "Documentation") |
479
814
  <!-- ALL-CONTRIBUTORS-LIST:END -->
480
815
 
481
816
  This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!