Skip to content

Client Island

A client island is a component which is mounted and rendered on the client side, but can also have a pre-rendered placeholder generated by the server.

Before a component can be used on the client you must first reference it in the /app/manifest.tsx, simply import the class to that file and the vite plugin will do the reset, however we also recommend exporting the component itself direct to prevent typescript from complaining.

import type { ClientIslandManifest } from "htmx-router";

import { TimeSince } from "~/component/client/time";
const Client = {
    TimeSince
};

export default Client as ClientIslandManifest<typeof Client>;

Once the component is referenced in the manifest you must use it from the manifest for it to be re-rendered on the client.

import Client from "~/manifest.tsx";

export function loader() {
  return <Client.TimeSince time={Date.now()}>
    A server rendered placeholder that will be replaced once the client mounts
  </Client.TimeSince>
}

Client Mounting

You must also import the manifest in your entry.client.ts or else the components will never mount.

entry.client.ts
import "~/manifest";

// ... the rest of your entry

// vite complains if the client entry doesn't have a default export
export default {};

Static Generation

If you define the client in your htmx.config.json you can have it statically generate the server and client versions of the manifest which you can import directly instead of relying on the vite plugin.

htmx.config.json
{
  "framework": "react",
  "client": {
    "source": "./app/manifest.tsx",
    "output": {
      "server": "./app/manifest.server.tsx",
      "client": "./app/manifest.client.tsx",
    }
  }
}