Skip to main content
Radix UI Primitives work seamlessly with server-side rendering (SSR) and React Server Components (RSC). All components are designed to be SSR-compatible and handle hydration correctly.

Compatibility

Radix Primitives are fully compatible with:
  • Next.js App Router (React Server Components)
  • Next.js Pages Router
  • Remix
  • Any React SSR framework
All Radix components are client components by default. While they don’t include explicit 'use client' directives in the source, they require client-side JavaScript for interactivity.

Using with Next.js App Router

When using Radix Primitives in the Next.js App Router, you’ll need to mark files that use them with the 'use client' directive since they require client-side interactivity.
1

Install the component

2

Create a client component

Create a separate component file and add the 'use client' directive:
3

Use in Server Components

You can now import and use your client component in Server Components:

Hydration Considerations

Radix Primitives handle hydration automatically, but there are some best practices to follow:

Avoid Hydration Mismatches

Ensure that the server-rendered HTML matches the client-rendered output. Avoid using browser-only APIs during initial render:

Portal Behavior

Components that use portals (Dialog, Popover, Tooltip, etc.) will render to document.body by default. This works correctly with SSR as portals are only activated on the client:
You can specify a custom container:

Form Components and SSR

Form components like Switch and Checkbox work seamlessly with SSR and progressive enhancement:
Form controls include hidden inputs that work even before JavaScript loads, providing progressive enhancement.

Testing SSR

The Radix repository includes a comprehensive SSR testing app using Next.js 15 with the App Router. You can reference this for examples of every component working with SSR:

Common Patterns

Wrap Components for Reusability

Create wrapper components with the 'use client' directive:

Lazy Loading Components

For better performance, lazy load dialog and overlay components:
When using ssr: false, the component won’t be rendered during SSR. Use this only when necessary.

Troubleshooting

”Cannot read property of undefined” errors

This usually happens when components try to access browser APIs during SSR. Wrap browser-specific code in useEffect or check for typeof window !== 'undefined'.

Hydration warnings

Ensure that:
  • Server and client render the same initial output
  • You’re not using browser-only APIs during initial render
  • Random values or dates are consistent between server and client

Portal components not appearing

Make sure your app has a root element where portals can render. Next.js provides this automatically with the <body> tag.