@creativecreate/react-auto-headings
v1.0.5
Published
A React component library for automatic heading management
Maintainers
Readme
@creativecreate/react-auto-headings
A React component library for automatic heading level management with semantic HTML support.
Maintaining proper heading hierarchy across different components and pages can be challenging — you need to manually track heading levels, ensure semantic correctness when reusing components in different contexts, and maintain accessibility standards (like having only one H1 per page). Additionally, integrating custom heading components from UI libraries (like ShadCN, Material-UI, or Bootstrap) while preserving semantic structure becomes complex. This package tackles these challenges by providing a context-aware, automatic heading level system that handles everything for you. Use headings freely across any component without worrying about level tracking or semantic correctness; the library automatically determines the correct heading level based on component hierarchy. With support for custom heading components and flexible prop mapping, you can easily integrate any UI library's heading components while maintaining proper semantic HTML structure. Use AutoHeadingGroup to create nested sections and ensure proper heading hierarchy (one H1, then H2, H3, etc.).
Features
- 🎯 Smart dynamic tracking: Intelligently identifies and maintains correct heading order (h1-h6) automatically — even when
<AutoHeading>components are defined in completely different components, reused across pages, or nested in various contexts. No manual level tracking required; the system dynamically adapts to your component hierarchy. - 🎨 Custom component integration: Reuse your design library's heading components (ShadCN, Material-UI, Bootstrap, or custom) with all their available props — no need to modify your components or lose any functionality. Flexible
prop mappingtransforms your custom component's props seamlessly, allowing your custom component to work exactly as it normally would while gaining automatic heading level management. - 🎛️ Highly customizable: Take full control when you need it — override heading levels with the
levelprop, apply customclassNameandidattributes, pass any standard HTML attributes (style, aria-, data-, event handlers), or forward custom props to your design library components. - 🏗️ Semantic structure & nested sections: Create perfectly structured heading hierarchies effortlessly with
AutoHeadingGroup— automatically generates proper semantic HTML (h1 → h2 → h3...) that screen readers, search engines, and accessibility tools love. No more broken heading sequences or accessibility violations; just wrap your sections and watch the magic happen. - 📦 TypeScript support: Full TypeScript support with type-safe custom props
- 🔧 Zero configuration: Works out of the box with sensible defaults
- 🌐 Framework-agnostic: Compatible with Next.js App Router (see integration guide), Remix, Vite, and other React frameworks
Installation
npm install @creativecreate/react-auto-headingsNext.js App Router
⚠️ Important for Next.js Users: This package uses React Context, which requires client components. If you're using Next.js App Router, you may encounter server/client boundary errors. See our Next.js Integration Guide for detailed instructions on:
- Setting up
AutoHeadingProviderin layouts without breaking SSR/SSG- Handling server/client component boundaries
- Common errors and solutions (like
createContext is not a function)- Best practices for preserving server-side rendering
Quick Fix: If you see createContext is not a function errors, mark components using AutoHeading with 'use client' or extract the UI into a separate client component. See the Next.js guide for complete examples.
Basic Usage
1. Wrap your app with AutoHeadingProvider
import { AutoHeadingProvider } from '@creativecreate/react-auto-headings';
function App() {
return (
<AutoHeadingProvider startLevel={1}>
{/* Your app content */}
</AutoHeadingProvider>
);
}2. Use AutoHeading components
import { AutoHeading, AutoHeadingGroup } from '@creativecreate/react-auto-headings';
function MyComponent() {
return (
<div>
<AutoHeading>Main Title</AutoHeading>
<p>Some content here...</p>
</div>
);
}Output:
- renders as
<h1>Main Title</h1>
Note: See Example 3: Reusable Component with AutoHeading for more detailed example for using with components.
3. Create nested sections with AutoHeadingGroup
import { AutoHeading, AutoHeadingGroup } from '@creativecreate/react-auto-headings';
function MyComponent() {
return (
<div>
<AutoHeading>Main Title</AutoHeading>
<AutoHeadingGroup>
<AutoHeading>Section Title</AutoHeading>
<AutoHeadingGroup>
<AutoHeading>Subsection Title</AutoHeading>
</AutoHeadingGroup>
<AutoHeading>Another Section</AutoHeading>
</AutoHeadingGroup>
</div>
);
}Output:
<h1>Main Title</h1><h2>Section Title</h2><h3>Subsection Title</h3><h2>Another Section</h2>
Important: For proper semantic HTML, you should have only one H1 per page. Use AutoHeadingGroup to create nested sections (h2, h3, etc.) instead of having multiple H1 tags.
Advanced Usage
Using Custom Heading Components
You can use any custom heading component from UI libraries like ShadCN, Material-UI, or your own custom components:
import { AutoHeadingProvider, AutoHeading } from '@creativecreate/react-auto-headings';
import { Heading } from '@/components/ui/heading'; // Your custom heading component
function App() {
return (
<AutoHeadingProvider
startLevel={1}
customHeader={Heading}
customHeaderPropMapper={(level, props) => ({
...props,
level: level as 1 | 2 | 3 | 4 | 5 | 6,
variant: `h${level}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6',
})}
>
<AutoHeading>Page Title</AutoHeading>
<AutoHeadingGroup>
<AutoHeading>Section Title</AutoHeading>
</AutoHeadingGroup>
</AutoHeadingProvider>
);
}Passing Custom Props to AutoHeading
When using a custom heading component, you can pass custom props directly to AutoHeading, and they'll be forwarded to your custom component:
import { AutoHeading } from '@creativecreate/react-auto-headings';
import { Heading } from '@/components/ui/heading';
function MyComponent() {
return (
<AutoHeading weight="semibold" font="secondary">
Custom Styled Title
</AutoHeading>
);
}Custom Prop Mapping
The customHeaderPropMapper function allows you to transform props from AutoHeading to match your custom component's API:
<AutoHeadingProvider
customHeader={CustomHeading}
customHeaderPropMapper={(level, autoHeadingProps) => {
// Transform props to match your custom component
return {
...autoHeadingProps,
size: `h${level}`, // Map level to 'size' prop
variant: 'default',
// Add any other transformations
};
}}
>
<AutoHeading>Title</AutoHeading>
</AutoHeadingProvider>Prop priority:
- User-provided props on
AutoHeading(highest priority) - Mapped props from
customHeaderPropMapper - Base props (level, className, id, etc.)
Level Override
You can override the automatic level determination when needed:
<AutoHeading level={3}>Force H3</AutoHeading>Custom Start Level
Set a custom starting level for your page or section:
<AutoHeadingProvider startLevel={2}>
{/* All headings start at h2 */}
<AutoHeading>This is H2</AutoHeading>
</AutoHeadingProvider>This is useful when you have a guaranteed h1 outside the provider (e.g., in your layout).
Nested Providers
You can nest providers with different configurations:
<AutoHeadingProvider startLevel={1}>
<AutoHeading>Level 1</AutoHeading>
<AutoHeadingProvider startLevel={3} customHeader={DifferentHeading}>
<AutoHeading>Level 3 with Different Component</AutoHeading>
</AutoHeadingProvider>
</AutoHeadingProvider>API Reference
AutoHeadingProvider
The context provider that manages heading levels and custom component configuration.
Props:
children: ReactNode- Your app contentstartLevel?: number- Starting heading level (default:1). Clamped between 1 and 6.customHeader?: ComponentType<T>- Optional custom component to use for allAutoHeadinginstances within this providercustomHeaderPropMapper?: CustomHeaderPropMapper<T>- Optional function to map/transform props fromAutoHeadingto your custom componenttype CustomHeaderPropMapper<T> = ( level: number, autoHeadingProps: Record<string, any> ) => Partial<T>;
Example:
<AutoHeadingProvider
startLevel={1}
customHeader={Heading}
customHeaderPropMapper={(level, props) => ({
...props,
level: level as 1 | 2 | 3 | 4 | 5 | 6,
variant: `h${level}`,
})}
>
{children}
</AutoHeadingProvider>AutoHeading
Component that automatically determines and renders the correct heading level.
Props:
children: ReactNode- The heading contentlevel?: number- Optional override for the heading level (1-6). Clamped to valid range.className?: string- Optional CSS class nameid?: string- Optional HTML id attribute...props- All other HTML attributes and custom props (when using custom components)
Example:
<AutoHeading className="my-heading" id="main-title">
Page Title
</AutoHeading>With custom props (when using custom component):
<AutoHeading<HeadingProps> weight="bold" font="sans">
Custom Styled Title
</AutoHeading>AutoHeadingGroup
Component that increments the heading level by 1 for its children, creating nested sections.
Props:
children: ReactNode- Child components (typicallyAutoHeadingcomponents)
Example:
<AutoHeadingGroup>
<AutoHeading>Section Title</AutoHeading>
<AutoHeadingGroup>
<AutoHeading>Subsection Title</AutoHeading>
</AutoHeadingGroup>
</AutoHeadingGroup>Note: AutoHeadingGroup preserves customHeader and customHeaderPropMapper from the parent context, so custom components work seamlessly in nested groups.
useHeadingContext
Hook to access the heading context (useful for custom components or advanced use cases).
Returns:
{
level: number;
customHeader?: ComponentType<T>;
customHeaderPropMapper?: CustomHeaderPropMapper<T>;
}Example:
import { useHeadingContext } from '@creativecreate/react-auto-headings';
function CustomComponent() {
const context = useHeadingContext();
// context.level, context.customHeader, etc.
}ExtractComponentProps
Type helper to extract props from a component type for type-safe custom props.
Usage:
import { ExtractComponentProps } from '@creativecreate/react-auto-headings';
import { Heading } from '@/components/ui/heading';
type HeadingProps = ExtractComponentProps<typeof Heading>;
<AutoHeading<HeadingProps> weight="bold">Title</AutoHeading>TypeScript
The package is written in TypeScript and includes full type definitions. All types are exported from the main entry point.
Type-Safe Custom Props
When using custom heading components, you can achieve full type safety:
import { AutoHeading, ExtractComponentProps } from '@creativecreate/react-auto-headings';
import { Heading } from '@/components/ui/heading';
type HeadingProps = ExtractComponentProps<typeof Heading>;
// Now you get full type checking for custom props
<AutoHeading<HeadingProps>
weight="semibold" // ✅ Type-checked
font="secondary" // ✅ Type-checked
invalidProp={123} // ❌ TypeScript error
>
Title
</AutoHeading>Generic Type Support
Both AutoHeading and AutoHeadingProvider support generic types for custom props:
// Define your custom props type
type CustomHeadingProps = {
weight?: 'light' | 'regular' | 'semibold';
font?: 'primary' | 'secondary';
};
// Use it with AutoHeadingProvider
<AutoHeadingProvider<CustomHeadingProps> customHeader={Heading}>
<AutoHeading<CustomHeadingProps> weight="semibold" font="secondary">
Title
</AutoHeading>
</AutoHeadingProvider>Examples
Example 1: Basic Usage with Native Headings
import { AutoHeadingProvider, AutoHeading, AutoHeadingGroup } from '@creativecreate/react-auto-headings';
function Article() {
return (
<AutoHeadingProvider startLevel={1}>
<article>
<AutoHeading>Article Title</AutoHeading>
<p>Introduction paragraph...</p>
<AutoHeadingGroup>
<AutoHeading>First Section</AutoHeading>
<p>Section content...</p>
<AutoHeadingGroup>
<AutoHeading>Subsection</AutoHeading>
<p>Subsection content...</p>
</AutoHeadingGroup>
</AutoHeadingGroup>
<AutoHeadingGroup>
<AutoHeading>Second Section</AutoHeading>
<p>More content...</p>
</AutoHeadingGroup>
</article>
</AutoHeadingProvider>
);
}Renders:
<h1>Article Title</h1><h2>First Section</h2><h3>Subsection</h3><h2>Second Section</h2>
Example 2: Integration with ShadCN/UI
import { AutoHeadingProvider, AutoHeading } from '@creativecreate/react-auto-headings';
import { Heading } from '@/components/ui/heading'; // ShadCN-style component
function App() {
return (
<AutoHeadingProvider
startLevel={1}
customHeader={Heading}
customHeaderPropMapper={(level, props) => ({
...props,
level: level as 1 | 2 | 3 | 4 | 5 | 6,
variant: `h${level}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6',
})}
>
<AutoHeading>Page Title</AutoHeading>
<AutoHeadingGroup>
<AutoHeading weight="semibold">Section</AutoHeading>
</AutoHeadingGroup>
</AutoHeadingProvider>
);
}Example 3: Reusable Component with AutoHeading
import { AutoHeading } from '@creativecreate/react-auto-headings';
// This component can be used anywhere and will automatically
// get the correct heading level based on context
function SectionTitle({ children }: { children: React.ReactNode }) {
return (
<AutoHeading className="section-title">
{children}
</AutoHeading>
);
}
// Use it in different contexts:
function Page() {
return (
<AutoHeadingProvider startLevel={1}>
<SectionTitle>Main Title</SectionTitle> {/* Renders as h1 */}
<AutoHeadingGroup>
<SectionTitle>Section</SectionTitle> {/* Renders as h2 */}
<AutoHeadingGroup>
<SectionTitle>Subsection</SectionTitle> {/* Renders as h3 */}
</AutoHeadingGroup>
</AutoHeadingGroup>
</AutoHeadingProvider>
);
}Best Practices
- Always wrap your app/page with AutoHeadingProvider - This ensures proper heading level management
- Use only one H1 per page - For proper semantic HTML and SEO, have a single H1 (your main page title) and use
AutoHeadingGroupfor all other sections - Use AutoHeadingGroup for nested sections - This creates proper semantic hierarchy (h2, h3, etc.) instead of multiple H1 tags
- Set appropriate startLevel - If you have a guaranteed h1 outside the provider, start at level 2
- Use level override sparingly - Let the automatic system handle levels unless you have a specific need
- Maintain semantic structure - Don't skip heading levels (e.g., h1 → h3) for accessibility
- Type your custom props - Use
ExtractComponentPropsor define types explicitly for type safety
Example of correct usage:
<AutoHeadingProvider startLevel={1}>
<AutoHeading>Page Title</AutoHeading> {/* Single H1 */}
<AutoHeadingGroup>
<AutoHeading>Section 1</AutoHeading> {/* H2 */}
<AutoHeading>Section 2</AutoHeading> {/* H2 */}
</AutoHeadingGroup>
</AutoHeadingProvider>Avoid this pattern (multiple H1s):
<AutoHeadingProvider startLevel={1}>
<AutoHeading>Title 1</AutoHeading> {/* H1 */}
<AutoHeading>Title 2</AutoHeading> {/* H1 - semantically incorrect */}
</AutoHeadingProvider>Accessibility
The package ensures proper semantic HTML structure by:
- Rendering correct
<h1>through<h6>tags - Maintaining proper heading hierarchy
- Supporting all standard HTML attributes (id, className, aria-*, etc.)
- Working with screen readers and assistive technologies
License
MIT
