React Wrap Balancer
React Wrap Balancer is a React component designed to improve the readability of text, particularly titles and headings, by intelligently balancing line wraps to prevent awkward single-word lines or uneven text blocks. Its current stable version is 1.1.1, with an active release cadence that frequently introduces bug fixes and minor enhancements. A key differentiator is its ability to automatically detect and prioritize the native CSS `text-wrap: balance` property for optimal performance, falling back to a JavaScript-based solution when native browser support is unavailable. For applications utilizing multiple `<Balancer>` instances, the optional `<Provider>` component is recommended to centralize and share the re-balancing logic, which reduces HTML size and improves overall efficiency, especially when the native CSS feature is not available. The library ships with TypeScript types, ensuring a robust developer experience.
Common errors
-
ReferenceError: ResizeObserver is not defined
cause The browser or environment running the code does not support the `ResizeObserver` API, which `react-wrap-balancer` uses for dynamic text re-balancing.fixUpgrade your browser to a version that supports `ResizeObserver` (e.g., Chrome 64+, Firefox 69+, Safari 13.1+) or include a `ResizeObserver` polyfill in your project. -
Warning: Extra attributes from the server. This is a hydration error. Your app may not render correctly.
cause Inconsistencies between the server-rendered and client-rendered HTML, often related to dynamically injected scripts or attributes, which were present in early versions.fixEnsure you are using `react-wrap-balancer` version `0.2.4` or higher, which includes a fix for hydration warnings on script tags. If using CSP, provide a `nonce` prop. -
Balancer not correctly setting text-wrap: balance
cause The native CSS `text-wrap: balance` might not be detected or applied, or the JavaScript fallback is not engaging as expected. This was a specific bug fixed in version 1.1.0.fixUpgrade to `react-wrap-balancer@1.1.0` or newer. Ensure `<Provider>` is wrapping your application. If you explicitly want to force the JavaScript fallback, set `preferNative={false}` on the `<Balancer>` component, though this is generally less performant.
Warnings
- breaking Starting with v1.0, `react-wrap-balancer` prioritizes the native CSS `text-wrap: balance` feature. If native support is detected, the `ratio` prop on `<Balancer>` components will be ignored.
- gotcha When using multiple `<Balancer>` components, it is strongly recommended to wrap your entire application or the relevant section with the `<Provider>` component. This allows for shared re-balance logic, reduces HTML size, and optimizes performance.
- gotcha The library relies on the `ResizeObserver` API for responsive balancing. Older browsers or environments without `ResizeObserver` support (e.g., IE) will not function correctly.
- gotcha If you are using Content Security Policy (CSP), the inline script tags generated by `react-wrap-balancer` will require a `nonce` attribute to be allowlisted. Otherwise, a CSP error will occur.
- gotcha Placing `<Balancer>` within an element that has `display: flex` or `display: grid` can sometimes lead to unexpected layout issues or incorrect balancing, especially if the flex/grid container's sizing interferes with the text flow.
Install
-
npm install react-wrap-balancer -
yarn add react-wrap-balancer -
pnpm add react-wrap-balancer
Imports
- Balancer
import { Balancer } from 'react-wrap-balancer'import Balancer from 'react-wrap-balancer'
- Provider
import Provider from 'react-wrap-balancer'
import { Provider } from 'react-wrap-balancer' - BalancerProps
import type { BalancerProps } from 'react-wrap-balancer'
Quickstart
import { Provider } from 'react-wrap-balancer';
import Balancer from 'react-wrap-balancer';
import React from 'react';
import ReactDOM from 'react-dom/client';
function App() {
return (
<Provider>
<div style={{ maxWidth: '400px', margin: '50px auto', fontFamily: 'sans-serif' }}>
<h1>
<Balancer>
This is a very long title that needs to be perfectly balanced for optimal readability across various screen sizes.
</Balancer>
</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<h2>
<Balancer ratio={0.8}>
Another balanced subtitle for improved typography.
</Balancer>
</h2>
</div>
</Provider>
);
}
const root = ReactDOM.createRoot(document.getElementById('root') ?? document.createElement('div'));
root.render(<App />);