Browser JS, islands & hydration

Tropical pages (and the React components you use to build them) are only server-rendered by default.

For example, this component would render a button in your page's prerendered HTML, but the click handler won't automatically work.

const HiButton = ({ name }) => (
  <button onClick={() => alert(`hi ${name}`)}>
    Hi
  </button>
)

By default, the component isn't included in the browser JS bundle (src/entry-client.jsx), nor is the server-rendered HTML hydrated.

You can hydrate or progressively enhance server-rendered HTML in Tropical however you wish, even without using React in the browser!

In src/entry-client.jsx you can manually add event listeners with vanilla JS, or use a library like Stimulus or viewloader for a more structured approach.

Of course, there are advantages to using React in the browser, regardless of whether you're hydrating server-rendered HTML or doing something purely client-side.

Islands and partial hydration

Tropical encourages an Islands architecture for taking full advantage of React. In React terms, it means we only want to hydrate specific parts of the page (aka partial hydration) rather than hydrating a single root "page" component and everything it contains.

You can do this with the included tropical-islands package.

Use <Island> in your server-rendered pages and components:

import { Island } from 'tropical-islands'

export const MyPage = () => (
  <>
    <StaticThing />
    <Island componentName='HiButton'>
      <HiButton name='Debbie' />
    </Island>
    <AnotherStaticThing />
  </>
)

Then use hydrateComponents in the browser JS bundle src/entry-client.jsx:

import { hydrateIslands } from 'tropical-islands'
import { HiButton } from './components/HiButton'

hydrateIslands({
  HiButton
})

See the tropical-islands docs for more detailed usage instructions for <Island> and hydrateIslands.


Next: Layouts