Server-Side Rendering

Superglue's generators does not include Server Side Rendering, but we can add support using Humid, a SSR library built for Superglue.

Follow the instructions. Then, if you're using esbuild, create a app/javascript/server_rendering.js:

import React from 'react';
import { Application } from '@thoughtbot/superglue';
import { buildVisitAndRemote } from './application_visit';
import { pageIdentifierToPageComponent } from './page_to_page_mapping';
import { store } from './store'
import { renderToString } from 'react-dom/server';

require("source-map-support").install({
  retrieveSourceMap: filename => {
    return {
      url: filename,
      map: readSourceMap(filename)
    };
  }
});

setHumidRenderer((json, baseUrl, path) => {
  const initialState = JSON.parse(json)
  return renderToString(
    <Application
      className="full-height"
      // The base url prefixed to all calls made by the `visit`
      // and `remote` thunks.
      baseUrl={baseUrl}
      // The global var SUPERGLUE_INITIAL_PAGE_STATE is set by your erb
      // template, e.g., application/superglue.html.erb
      initialPage={initialState}
      // The initial path of the page, e.g., /foobar
      path={path}
      // Callback used to setup visit and remote
      buildVisitAndRemote={buildVisitAndRemote}
      // Callback used to setup the store
      store={store}
      // Mapping between the page identifier to page component
      mapping={pageIdentifierToPageComponent}
    />,
    {
      concurrentFeatures: false,
    }
  )
})

Next

and add a esbuild build file.

Add a shim.js for the above. We'll need this for the v8 environment that mini-racer runs on.

Add a line to your package.json like so:

Use Humid.render in all your html templates, e.g., index.html.erb or superglue.html.erb:

!> Do not render spacing inside of <div id="app">. If you do, React will not hydrate properly and warn Hydration failed because the initial UI does not match what was rendered on the server

Change your application.js to use hydrateRoot:

and change the rest of application.js accordingly. For example:

and add build script your package.json to build both the client and server js bundles. For example:

Last updated

Was this helpful?