React Helmet
A React adapter over @mongez/dom’s metadata module. One <Helmet> component that sets the document title (with optional app-name suffix), description, keywords, Open Graph / Twitter cards, canonical URL, and <html> attributes. Effect-only — returns null, writes directly to document.head and document.documentElement, restores prior values on unmount.
Highlighted features
One prop fans out
<Helmet title=“X” /> writes <title>, og:title, twitter:title, and itemprop=name in one go. Same for description, image, URL.
Auto-restore on unmount
Each effect snapshots the mount-time value. Unmount cleanly restores — perfect for client-side route transitions that briefly mount one Helmet and then another.
App-wide defaults
setHelmetConfigurations({ appName, titleSeparator, …, translationFunction }) — set once, every <Helmet> instance inherits. Per-call props win.
SSR-safe import
document is read lazily inside helpers, not at module top. Importing in a Node SSR context doesn’t throw — writes happen in client effects, so SSR is a clean no-op.
Install
npm install @mongez/react-helmet @mongez/domyarn add @mongez/react-helmet @mongez/dompnpm add @mongez/react-helmet @mongez/domPeer deps: react >= 18, @mongez/dom >= 1.1.2.
Quick peek
import Helmet from "@mongez/react-helmet";
export default function ArticlePage({ post }) { return ( <> <Helmet title={post.title} description={post.summary} keywords={post.tags} image={post.coverImage} /> <Article post={post} /> </> );}Drop <Helmet> anywhere in the tree — every prop fans out to the matching <head> tags. Unmount restores the prior values automatically.
Mental model
| Concept | What it is |
|---|---|
<Helmet> | Side-effect renderer — returns null. Every prop maps to an effect that writes one or more <head> tags. |
HelmetProps | Per-instance settings. Each maps to a known set of tags. |
setHelmetConfigurations | App-wide defaults. Per-call props win when both are provided. |
translationFunction | Optional (key) => string — auto-translates the title and appName through @mongez/localization. |
Lifecycle
<Helmet title=… description=… /> │ ▼mount → one effect per prop → writes to document.head / documentElement │ ▼re-render with new prop → effect with that prop in deps re-runs → overwrites the tag │ ▼unmount → each effect's cleanup restores the mount-time snapshottitle, description, keywords, image, url, pageId, className, and htmlAttributes all restore reliably.
Scope boundaries
| Concern | Lives where | Why |
|---|---|---|
| DOM-level title / meta writers | @mongez/dom | Framework-agnostic |
| React component + config singleton | This package | React-specific |
| Translation strings | @mongez/localization | Pluggable via translationFunction |
SSR
document.documentElement is accessed lazily inside helper functions, not at the module top level — importing @mongez/react-helmet in a Node SSR context does not throw. All writes happen in client-side effects, so the component is a no-op during server render. For Next.js App Router, wrap in a "use client" boundary; for Pages Router / Remix, use dynamic(..., { ssr: false }).
Where to go next
- The Helmet component — full prop list, mount/unmount semantics
- Metadata — which tags each prop writes
- Configuration —
setHelmetConfigurations, app-wide defaults, translation function - Recipes — common patterns (article pages, dark mode, route transitions)