{"id":11715,"library":"react-helmet-async","title":"Thread-safe Async React Helmet","description":"react-helmet-async is a robust solution for managing document head tags (title, meta, link, etc.) in React applications, designed to be thread-safe for server-side rendering (SSR). It addresses the limitations of the original `react-helmet` by encapsulating state on a per-request basis through a `<HelmetProvider>`, crucial for asynchronous SSR environments. The current stable version is 3.0.0, which introduces significant adaptations for React 19+, leveraging React's native metadata hoisting capabilities while maintaining backward compatibility for React 16-18. It differentiates itself by providing a consistent API across React versions, handling `htmlAttributes` and `bodyAttributes` consistently, and offering a context for SSR data extraction, although this context behaves differently in React 19. Releases appear to follow a non-strict cadence, driven by major React version updates and feature enhancements.","status":"active","version":"3.0.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/staylor/react-helmet-async","tags":["javascript","typescript"],"install":[{"cmd":"npm install react-helmet-async","lang":"bash","label":"npm"},{"cmd":"yarn add react-helmet-async","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-helmet-async","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core React dependency for UI component rendering. Required peer dependency.","package":"react","optional":false}],"imports":[{"note":"The default export was removed in version 1.0.0. Named import is required since then.","wrong":"import Helmet from 'react-helmet-async';","symbol":"Helmet","correct":"import { Helmet } from 'react-helmet-async';"},{"note":"Essential for encapsulating Helmet state, especially for SSR. Primarily designed for ESM usage.","wrong":"const { HelmetProvider } = require('react-helmet-async');","symbol":"HelmetProvider","correct":"import { HelmetProvider } from 'react-helmet-async';"},{"note":"For server-side rendering, state is extracted from the `context` object passed to `HelmetProvider`, replacing the deprecated `renderStatic()` method from prior `react-helmet` versions. In React 19, the context will not be populated for `<title>`, `<meta>`, `<link>` as React handles them natively.","wrong":"Helmet.renderStatic();","symbol":"HelmetServerState (conceptual)","correct":"const { helmet } = helmetContext;"}],"quickstart":{"code":"import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\n\nconst App = () => (\n  <div>\n    <Helmet>\n      <html lang=\"en\" amp />\n      <title>My Awesome App</title>\n      <meta name=\"description\" content=\"A basic example of react-helmet-async.\" />\n      <link rel=\"canonical\" href=\"https://example.com/\" />\n      <style>{`body { background-color: #f0f0f0; }`}</style>\n      <script type=\"application/ld+json\">\n        {\n          \"@context\": \"https://schema.org\",\n          \"@type\": \"WebSite\",\n          \"url\": \"https://example.com/\",\n          \"name\": \"My Awesome App\"\n        }\n      </script>\n    </Helmet>\n    <h1>Welcome to My Awesome App!</h1>\n    <p>Check the document head for meta tags.</p>\n  </div>\n);\n\nconst rootElement = document.getElementById('app');\nif (rootElement) {\n  createRoot(rootElement).render(\n    <HelmetProvider>\n      <App />\n    </HelmetProvider>\n  );\n} else {\n  console.error('Root element #app not found!');\n}\n","lang":"typescript","description":"This quickstart demonstrates basic client-side usage of Helmet for managing document head attributes, title, meta, link, style, and script tags within a React application, wrapped in a HelmetProvider."},"warnings":[{"fix":"Update all imports to use named imports: `import { Helmet, HelmetProvider } from 'react-helmet-async';`","message":"Starting with version 1.0.0, the package no longer provides a default export. Attempting to use `import Helmet from 'react-helmet-async'` will result in a runtime error.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"If you rely on the SSR `context` object to extract `<title>`, `<meta>`, or `<link>` tags in a React 19 environment, you should instead render these tags directly in your component tree. React 19 will hoist them natively. For `htmlAttributes` and `bodyAttributes`, the context and direct DOM manipulation remain relevant.","message":"For React 19+, `<HelmetProvider>` becomes a transparent passthrough for `<title>`, `<meta>`, and `<link>` elements, as React 19 handles their hoisting natively. The `context` object for SSR will *not* be populated with these elements when running on React 19. `htmlAttributes` and `bodyAttributes` are still applied via direct DOM manipulation.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always wrap your React application with `<HelmetProvider>`, both on the client and server. For SSR, ensure you pass a unique `context` object to `<HelmetProvider>` for each request.","message":"Using `react-helmet-async` without `<HelmetProvider>` will lead to incorrect state management, especially in server-side rendering or concurrent environments, as it relies on the provider to encapsulate state per request. This can cause cross-request data leakage.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"When migrating from `react-helmet`, remove `Helmet.renderStatic()` calls and instead pass a `context` object to `<HelmetProvider>` during SSR. Extract the `helmet` object from this `context` after rendering.","message":"The package is a fork of `react-helmet` specifically to address its thread-safety issues when performing asynchronous operations on the server. If migrating from `react-helmet`, ensure you replace all `Helmet.renderStatic()` calls with the `context` object extraction from `<HelmetProvider>`.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `import Helmet from 'react-helmet-async';` to `import { Helmet } from 'react-helmet-async';`","cause":"Attempting to use a default import for Helmet, but it was removed in v1.0.0.","error":"TypeError: Cannot destructure property 'Helmet' of 'react-helmet-async' as it is undefined."},{"fix":"Check for duplicate `react` installations using `npm ls react` or `yarn why react`. Use a tool like `resolutions` (Yarn) or `overrides` (NPM 8+) to force a single `react` version. Ensure `react` is correctly specified in `peerDependencies` and installed in your project.","cause":"This error can occur if `react` is duplicated in your `node_modules` or if `react-helmet-async` is incorrectly linked, causing it to use a different React instance than your application. This often happens with monorepos or mismatched peer dependency resolutions.","error":"Error: Invariant Violation: Hooks can only be called inside the body of a function component."},{"fix":"For React 19+, rely on React's native head hoisting for `<title>`, `<meta>`, and `<link>`. If you need to access these tags programmatically on the server, render them directly in your component tree instead of relying solely on `Helmet` and its context extraction.","cause":"When running on React 19+, `<title>`, `<meta>`, and `<link>` tags are handled natively by React's head hoisting. The `context` object passed to `HelmetProvider` will therefore not contain these specific tags.","error":"helmetContext.helmet is undefined (during SSR for React 19+)"}],"ecosystem":"npm"}