React Server Components overview
Hydrogen is modelled after React Server Components, an approach that offers an opinionated data-fetching and rendering workflow for React apps.
This guide provides information about how React Server Components work in the context of Hydrogen.
How React Server Components work
Anchor link to section titled "How React Server Components work"React Server Components allow the server and the client to work together to render your Hydrogen app.
For example, the following React element tree is composed of React components that render other React components. React Server Components allow some components to render on the server, some to render in the browser or on the server using server-side rendering (SSR), and others to render on both the server and the client:
Component types
Anchor link to section titled "Component types"React Server Components include the following component types:
Type | Description | Filename convention |
---|---|---|
Server | Components that fetch data and render content on the server. Their dependencies aren't in the client bundle. Server components don't include any client-side interactivity. Only server components can make calls to the Storefront API. | Server components end in .server.jsx . |
Client | Components that render on the client. Client components include client-side stateful interactivity. | Client components end in .client.jsx . |
Shared | Components that render on both the server and the client. | Shared components don't end in either .client.jsx or .server.jsx . |
React Server Components separate client and server logic. This separation provides the following benefits to Hydrogen apps:
- Server-only code that has no impact on bundle size and reduces bundle sizes
- Server-side access to custom and private server-side data sources
- Seamless integration and a well-defined protocol for server and client components
- Streaming rendering and progressive hydration
- Subtree and component-level updates that preserve client state
- Server and client code sharing, where appropriate
Constraints
Anchor link to section titled "Constraints"React Server Components have the following constraints on server and client components:
- Client components can’t access server-only features, like the filesystem, and can only import other client components.
- Server components can’t access client-only features, like state.
Due to these constraints, there are specific rules that you need to follow when building your Hydrogen app:
Composition
Anchor link to section titled "Composition"One of the key constraints of React Server Components is that you can't import and render server components from client components. However, you can compose React Server Components to take in props.
The following example shows how to pass a server component as a children
prop to a client component. The OuterServerComponent
can then instantiate both the client and server components. This is how you can have server components under client components in your React element tree.
Sending props
Anchor link to section titled "Sending props"When you send props to client components from a server component, make sure that the props are JSON-serializable. For example, functions or callbacks can't be passed as props.
The following prop would send successfully:
The following prop wouldn't send successfully:
Sharing code between server and client
Anchor link to section titled "Sharing code between server and client"In addition to server-specific and client-specific components, you can create components that work on both the server and the client. This allows logic to be shared across environments, as long as the components meet all the constraints of both the server and client components.
Although shared components have the most constraints, many components already obey these rules and can be used across the server and client without modification. For example, many components transform some props based on certain conditions, without using state or loading additional data. This is why shared components are the default and don’t have a dedicated file extension.
Client components and server-side rendering
Anchor link to section titled "Client components and server-side rendering"Client components ending in .client.jsx
are rendered in the browser. However, they are also rendered on the server during server-side rendering (SSR). This is because SSR produces an HTML "preview" of what will eventually be rendered in the browser.
This behavior might be confusing, because the word "client" indicates a client-only behavior. Shopify is working with the React team to refine these naming conventions to make it less confusing.
In the meantime, avoid including browser-only logic in client components in a way that will cause problems during SSR:
Component organization and index files
Anchor link to section titled "Component organization and index files"You might be familiar with a "facade file" pattern, where similar files are re-exported from a shared index.js
file in a folder. This pattern isn't supported in React Server Components when mixing client components with server components.
If you want to use the facade pattern, then you need to create separate files for client components and server components:
- Learn how to work with React Server Components.
- Improve your app's loading performance with streaming SSR and Suspense.