Skip to content

· views

How to slugify ReactNodes

I was working on a heading component that accepted either a string or a ReactNode as children. This heading component would then need to use the value provided to children to generate an id to be used on itself for use with anchor links.

To do this, I reached for slugify from @sindresorhus/slugify. In the instance a ReactNode is used, slugify would error because it only accepts a string as an argument. To fix this we can also make use of onlyText from react-children-utilities, which as the name implies, extracts only text from ReactNodes.

tsx
import slugify from '@sindresorhus/slugify';
import { onlyText } from 'react-children-utilities';
interface IHeading {
as?: 'h1' | 'h2' | 'h3';
children: string | React.ReactNode;
}
export default function Heading({
as: Component = 'h1',
children,
}: IHeading): JSX.Element {
const id = slugify(onlyText(children));
return <Component id={id}>{children}</Component>;
}

View CodeSandbox demo. H/T @kyleshevlin for the react-children-utilities link.