react-headings

HTML headings with auto-incrementing levels for WCAG compliance.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
react-headings
7233.2.1321 days ago3 years agoMinified + gzip package size for react-headings in KB

Readme

React Headings Logo
React Headings

<img alt="" src="https://img.shields.io/github/actions/workflow/status/alexnault/react-headings/ci-and-publish.yml?branch=master&style=for-the-badge">
<img alt="" src="https://img.shields.io/npm/v/react-headings?style=for-the-badge">
<img alt="" src="https://img.shields.io/bundlephobia/minzip/react-headings?style=for-the-badge">
<img alt="" src="https://img.shields.io/npm/dm/react-headings?style=for-the-badge">


Never worry about using the wrong heading level (h1, h2, etc.) in complex React apps!

React-headings maintains the proper hierarchy of headings for improved accessibility and SEO, no matter the component structure, while you keep full control of what's rendered.
References:

Table of contents

Demos

Highlights

  • Improves SEO and accessibility
  • Supports server-side rendering
  • Under 1 kB minified & gzipped
  • Typed with TypeScript
  • Fully tested
  • Works with any CSS solutions (Tailwind, CSS-in-JS, etc.)
  • Plays nicely with component libraries (Material UI, etc.)
  • Follows semantic versioning

Installation

npm install react-headings

Examples

Basic usage

import React from "react";
import { H, Section } from "react-headings";

function App() {
  return (
    <Section component={<H>My hx</H>}>
      <div>...</div>
      <div>...</div>
      <div>...</div>
      <Section component={<H>My hx+1</H>}>
        <div>...</div>
        <div>...</div>
        <div>...</div>
      </Section>
    </Section>
  );
}

Advanced structure

Child components inherit the current level of their parent:
import React from "react";
import { H, Section } from "react-headings";

function ParentComponent() {
  return (
    <Section component={<H>My hx</H>}>
      <Section component={<H>My hx+1</H>}>
        <Section component={<H>My hx+2</H>}>
          <ChildComponent />
        </Section>
      </Section>
    </Section>
  );
}

function ChildComponent() {
  return (
    <Section component={<H>My hy</H>}>
      {/* The following heading would be a <h5> in the current context */}
      <Section component={<H>My hy+1</H>}>
        <p>...</p>
      </Section>
    </Section>
  );
}

Styling

A heading can be styled like any ordinary <hx> element since it accepts all the same props:
import React from "react";
import { H, Section } from "react-headings";

function App() {
  return (
    <Section component={<H className="my-class">My hx</H>}>
      ...
    </Section>
  );
}

Custom heading

A heading can be as complex as we want:
import React from "react";
import { H, Section } from "react-headings";
import MyIcon from "./MyIcon";

function App() {
  return (
    <Section
      component={
        <div className="my-div">
          <MyIcon className="my-icon" />
          <H className="my-heading">My hx</H>
        </div>
      }
    >
      <div>...</div>
      <div>...</div>
      <div>...</div>
    </Section>
  );
}

Using component libraries

Leveraging Component and level from the context allows the use of component libraries. Here's an example with Material UI:
import React from "react";
import { useLevel } from "react-headings";
import { Typography } from "@material-ui/core";

function MyHeading(props) {
  const { Component } = useLevel();

  return <Typography component={Component} {...props} />;
}

API

<H> component

Renders a <h1>, <h2>, <h3>, <h4>, <h5> or <h6> depending on the current level.

Props

| Name | Type | Required | Description | | ---------- | ---------- | -------- | --------------------------------------------------------------- | | render | function | No | Override with a custom heading. Has precedence over children. | | children | node | No | The content of the heading. Usually the title. |
Any other props will be passed to the heading element.

Example

import React from "react";
import { H } from "react-headings";

function Example1() {
  return <H>This is my title</H>;
}

function Example2() {
  return (
    <H render={({ level, Component }) => <Component>My h{level}</Component>} />
  );
}

<Section> component

Creates a new section (a heading and its level).

Props

| Name | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------------------------------------- | | component | node | Yes | The heading component. Can be anything but best used in combination with <H>. | | children | node | No | The content of the new level. |

Example

import React from "react";
import { Section, H } from "react-headings";

function Example1() {
  return (
    <Section component={<H>This is my title</H>}>
      This is my content
    </Section>
  );
}

function Example2() {
  return (
    <Section
      component={
        <div>
          <div>
            <H>This is my title</H>
          </div>
        </div>
      }
    >
      This is my content
    </Section>
  );
}

useLevel hook

Returns an object containing the current level and current Component.

Arguments

None

Returns

| Name | Type | Description | | ----------- | -------------------------------------------------------- | ------------------------------------- | | level | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | The current level. | | Component | "h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" | The current component. Same as level. |

Example

import React from "react";
import { useLevel } from "react-headings";

function Example(props) {
  const { level, Component } = useLevel();

  return <Component {...props}>This is a h{level}</Component>;
}

Changelog

For a list of changes and releases, see the changelog.

Contributing

Found a bug, have a question or looking to improve react-headings? Open an issue, start a discussion or submit a PR!