Skip to main content

renderToString

renderToString synchronously renders a React tree to an HTML string. This is a legacy API that does not support Suspense or streaming.
renderToString does not support Suspense and cannot stream output. For new projects, use renderToPipeableStream (Node.js) or renderToReadableStream (Web Streams) instead.

Reference

renderToString(element, options?)

Renders a React element to an HTML string with React-specific attributes like data-reactroot.

Parameters

  • element: ReactNode - The React element to render
  • options: Object (optional)
    • identifierPrefix: string - Prefix for IDs generated by useId. Useful for avoiding conflicts when using multiple roots on the same page.

Returns

Returns a string containing the rendered HTML with React attributes.

Caveats

  • No Suspense support: If a component suspends, renderToString will throw an error
  • Blocking: Must wait for the entire tree to render before returning
  • No streaming: Cannot send HTML to client until everything is ready
  • Client-side: Also available in browser environments but not commonly used there

Usage

Basic server-side rendering

Using with Express

Setting identifier prefix

Use identifierPrefix to avoid ID conflicts when rendering multiple React roots on the same page:

Handling errors

renderToString throws errors synchronously, so use try-catch:

Limitations

No Suspense Support

If your component tree contains a Suspense boundary with a component that suspends, renderToString will throw an error:
Solution: Use renderToPipeableStream or renderToReadableStream which fully support Suspense.

Blocking Rendering

renderToString must render the entire component tree before returning:
Solution: Use streaming APIs to send HTML progressively as components become ready.

Performance Considerations

renderToString is synchronous and blocks the event loop:
Solution: Use streaming APIs which are non-blocking and allow concurrent request handling.

Migrating to Modern APIs

If you’re using renderToString, consider migrating to modern streaming APIs:

Runtime Availability

renderToString is available in multiple runtime exports:
Uses ReactDOMLegacyServerNode implementation.

Common Issues

renderToString cannot handle Suspense boundaries. Remove Suspense or migrate to renderToPipeableStream/renderToReadableStream.
Ensure server and client render identical HTML. Common causes:
  • Using Date.now() or Math.random() during render
  • Different data on server vs client
  • Browser-specific APIs used during render
renderToString builds the entire HTML string in memory. For very large pages, this can cause memory issues.Solution: Use streaming APIs which write directly to the response stream without buffering.

See Also