Tutorial
Hello World
For this tutorial, you will be building a "Hello World" page. It's one page, but we'll add complexity as we progress to highlight the power of Superglue.
Let's build a new rails project:
rails new tutorial -j esbuild --skip-hotwire!!! tip We're using esbuild here, but you can also use vite
then follow the installation instructions to setup Superglue.
Start with the usual
Let's begin by adding a route and a controller to an app.
=== "routes.rb"
in app/config/routes.rb
```ruby
resource :greet, only: :show
```=== "greets_controller.rb"
in app/controllers/greets_controller.rb
!!! tip Enable jsx rendering defaults
`use_jsx_rendering_defaults` enables Rails to look for `.jsx` files and
pairs with `.props` files. For example:
```
app/views
application/
superglue.html.erb
about/
index.jsx
users/
index.jsx
index.json.props
```
```ruby
class GreetsController < ApplicationController
before_action :use_jsx_rendering_defaults
def show
end
end
```Add the views
Next, let's add the following views.
app/views/greets/show.json.propsapp/views/greets/show.jsx
The Superglue installation generator also adds an application/superglue.html.erb, which
will be used as the default HTML template for every controller action.
Click the tabs below to see the contents:
=== "1. show.json.props"
If you've used Jbuidler, this should look familiar. Here, we're using
[props_template], a Jbuilder inspired templating DSL built for Superglue.
=== "2. show.jsx"
This is the page component that will receive the result of show.json.props.
=== "3. application/superglue.html.erb"
Connect the dots
The JSON payload that gets injected contains a componentIdentifier. We're
going to use the componentIdentifier to tie show.json.props to show.jsx so
Superglue knows which component to render with which response by modifyingapp/javascript/page_to_page_mapping.js.
!!! info
If you do not know what the componentIdentifier of a page is, you can
always go to the json version of the page on your browser to see what
gets rendered. In our case: http://localhost:3000/greet.json
=== "1. Example greet.json"
The layout for show.json.props is located at app/views/layouts/application.json.props. It
conforms to Superglue's payload response and uses the active_template_virtual_path as thecomponentIdentifier.
=== "2. page_to_page_mapping.js"
```js
import GreetsShow from '../views/greets/show'
Finish
Run bin/dev and go to http://localhost:3000/greet.
Productivity
That was quite an amount of steps to get to a Hello World. For simple functionality it's not immediately obvious where Superglue fits, but for medium complexity and beyond, Superglue shines where it can be clunky for tools like Turbo, Hotwire and friends.
Let's add some complexity to the previous sample.
!!! Sidequest
But first, A quick dive into [props_template] and how digging works. Click
on the tabs to see what happens when @path changes for the example below.
Continuing where we last left off
Let's add a 5-second sleep to show.json.props so every user is waiting for 5
seconds for every page load.
show.json.props
How should we improve the user experience?
Load the content later (Manual deferment)
What if we add a link on the page that would load the greeting async? Sounds like a good start, lets do that.
First, we'll use defer: :manual to tell props_template to skip over the
block.
=== "show.json.props"
=== "output"
=== "show.jsx"
Add a link
Now when the user lands on the page, we're no longer waiting 5 seconds. Lets add a link that will dig for the missing content to replace "Waiting for greet".
=== "show.json.props"
Add a URL for the href link with the props_at param. This is used on theapplication.json.props layout that instructs props_template to dig.
=== "show.jsx"
Superglue embraces Unobtrusive Javascript. Add a data-sg-remote to any link,
and Superglue will take care of making the fetch call.
Finish
And that's it. Now you have a button that will load content in an async fashion,
but how does it all work? Let's take a look at loadGreetPath
The shape of show.json.props is exactly the same as what is stored in the
redux store on pages["/greet"]. With a single keypath on props_at we
grabbed the content at data.greet from show.json.props AND stored it ondata.greet on pages["/greet"].
Now that's productive!
!!! tip
This show.jsx alternative does the same thing, but we're using the remote
function directly.
Improvements
In practice, there's a far simpler solution: defer: :auto, which would do all of the
above without a button.
=== "show.json.props"
The only change needed would be to use the :auto option with a placeholder.
The response would tell Superglue to:
=== "show.jsx"
Last updated
Was this helpful?