node.jsreactjsserver-side-renderingremix.run

How to render component only client side with Remix?


I have a three.js component that should only be rendered client side, how do I do this with Remix? Does Remix expose any utilities to help determine if we're in a server or client context? Could not find anything.

Here is an example of what I'm attempting to do with fictional hooks that don't exist in remix.

import React from 'react';
import { useRemixContext } from '@remix-run/react';

const MyComponent = () => {
  const remixContext = useRemixContext();
  if(remixContext.server) {
     return null;
  }
  return <div>Should only be rendered on the client</div>
}

Solution

  • One can use the ClientOnly component exposed by the remix-utils library, which takes a function returning a component as a child which will be rendered client side only.

    This component uses the hook useHydrated internally which is also exposed if you do not wish to use the component only for client side rendering.

    Note that in development mode this did not originally work for me, I don't know if this is because I'm using remix-deno template or that it just does not work in general with the live reload, but once deployed in production it worked like a charm.

    import React from 'react';
    import { ClientOnly } from "remix-utils";
    
    const App = () => {
      return <ClientOnly fallback={null}>
         {() => <MyComponent/>}
      </ClientOnly>
    }
    

    Also note that Suspense will eventually be released which should replace the above code.