staylor/react-helmet-async
staylor/react-helmet-async has 2,298 GitHub stars and 175 forks. GitHot measured -2 stars in 24 hours, -2 in 7 days, and -2 in 15 days. Last checked 2026-11-13 03:38 UTC. Last push 2026-03-03.
Thread-safe Helmet for React 16+ and friends
측정된 스타 증가
- in 24h
- -2
- in 7 days
- -2
- in 15 days
- -2
- in 1 month
- 기록 수집 중
서로 겹치는 기간의 순증가량이며 일별 합계가 아닙니다. 측정값이 없으면 비워 둡니다. 스타는 관심도를 나타내며 품질을 보장하지 않습니다.
README.md
Originalreact-helmet-async
Announcement post on Times Open blog
This package is a fork of React Helmet.
<Helmet> usage is synonymous, but server and client now requires <HelmetProvider> to encapsulate state per request.
react-helmet relies on react-side-effect, which is not thread-safe. If you are doing anything asynchronous on the server, you need Helmet to encapsulate data on a per-request basis, this package does just that.
React 19
React 19 has built-in support for hoisting <title>, <meta>, <link>, <style>, and <script> elements to <head>. Starting with version 3.0.0, this package detects the React version at runtime:
- React 19+:
<Helmet>renders actual DOM elements and lets React handle hoisting them to<head>.<HelmetProvider>becomes a transparent passthrough. The existing API is fully compatible — you do not need to change any code. - React 16–18: The existing behavior is preserved.
<Helmet>collects all instances, deduplicates tags, and applies changes to the DOM via manual manipulation (client) or serializes them for the response (server).
Note:
htmlAttributesandbodyAttributesdo not have a React 19 equivalent, so they are still applied via direct DOM manipulation on both code paths.
If you are starting a new React 19 project and do not need htmlAttributes/bodyAttributes, SSR context serialization, onChangeClientState, prioritizeSeoTags, or titleTemplate support, you may not need this package at all — React 19's built-in metadata handling may be sufficient.
Usage
New in 1.0.0: No more default export! import { Helmet } from 'react-helmet-async'
The main way that this package differs from react-helmet is that it requires using a Provider to encapsulate Helmet state for your React tree. If you use libraries like Redux or Apollo, you are already familiar with this paradigm:
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Helmet, HelmetProvider } from 'react-helmet-async';
const app = (
<HelmetProvider>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
createRoot(document.getElementById('app')).render(app);
On the server, we will no longer use static methods to extract state. react-side-effect
exposed a .rewind() method, which Helmet used when calling Helmet.renderStatic(). Instead, we are going
to pass a context prop to HelmetProvider, which will hold our state specific to each request.
import React from 'react';
import { renderToString } from 'react-dom/server';
import { Helmet, HelmetProvider } from 'react-helmet-async';
const helmetContext = {};
const app = (
<HelmetProvider context={helmetContext}>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
const html = renderToString(app);
const { helmet } = helmetContext;
// helmet.title.toString() etc…
React 19 SSR note: When using React 19,
<title>,<meta>, and<link>tags rendered inside<Helmet>are included directly in the React render output and hoisted to<head>by React itself. Thecontextobject will not be populated with helmet state on React 19. If you rely on thecontextfor server rendering, you can render these tags directly in your component tree instead and let React 19 handle them natively.
Streams
This package only works with streaming if your <head> data is output outside of renderToNodeStream().
This is possible if your data hydration method already parses your React tree. Example:
import through from 'through';
import { renderToNodeStream } from 'react-dom/server';
import { getDataFromTree } from 'react-apollo';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import template from 'server/template';
const helmetContext = {};
const app = (
<HelmetProvider context={helmetContext}>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
await getDataFromTree(app);
const [header, footer] = template({
helmet: helmetContext.helmet,
});
res.status(200);
res.write(header);
renderToNodeStream(app)
.pipe(
through(
function write(data) {
this.queue(data);
},
function end() {
this.queue(footer);
this.queue(null);
}
)
)
.pipe(res);
React 19: React 19's
renderToReadableStreamnatively handles<title>,<meta>, and<link>hoisting during streaming, so the manual context extraction shown above is not necessary.
Usage in Jest
While testing in using jest, if there is a need to emulate SSR, the following string is required to have the test behave the way they are expected to.
import { HelmetProvider } from 'react-helmet-async';
HelmetProvider.canUseDOM = false;
This is only relevant for React 16–18. On React 19,
HelmetProvideris a passthrough andcanUseDOMhas no effect.
Prioritizing tags for SEO
It is understood that in some cases for SEO, certain tags should appear earlier in the HEAD. Using the prioritizeSeoTags flag on any <Helmet> component allows the server render of react-helmet-async to expose a method for prioritizing relevant SEO tags.
In the component:
<Helmet prioritizeSeoTags>
<title>A fancy webpage</title>
<link rel="notImportant" href="https://www.chipotle.com" />
<meta name="whatever" value="notImportant" />
<link rel="canonical" href="https://www.tacobell.com" />
<meta property="og:title" content="A very important title"/>
</Helmet>
In your server template:
<html>
<head>
${helmet.title.toString()}
${helmet.priority.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
${helmet.script.toString()}
</head>
...
</html>
Will result in:
<html>
<head>
<title>A fancy webpage</title>
<meta property="og:title" content="A very important title"/>
<link rel="canonical" href="https://www.tacobell.com" />
<meta name="whatever" value="notImportant" />
<link rel="notImportant" href="https://www.chipotle.com" />
</head>
...
</html>
A list of prioritized tags and attributes can be found in constants.ts.
React 19: The
prioritizeSeoTagsflag has no effect on React 19, since tags are rendered as regular JSX elements and their order in<head>is determined by React's rendering order.
Usage without Context
You can optionally use <Helmet> outside a context by manually creating a stateful HelmetData instance, and passing that stateful object to each <Helmet> instance:
import React from 'react';
import { renderToString } from 'react-dom/server';
import { Helmet, HelmetData } from 'react-helmet-async';
const helmetData = new HelmetData({});
const app = (
<App>
<Helmet helmetData={helmetData}>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
);
const html = renderToString(app);
const { helmet } = helmetData.context;
React 19: The
helmetDataprop is ignored on React 19, since<Helmet>renders elements directly without the need for external state management.
Compatibility
| React Version | Behavior |
|---|---|
| 16.6+ | Full support via HelmetProvider context and manual DOM updates |
| 17.x | Full support via HelmetProvider context and manual DOM updates |
| 18.x | Full support via HelmetProvider context and manual DOM updates |
| 19.x+ | Renders native JSX elements; React handles <head> hoisting |
Development
pnpm install
pnpm test # unit tests
pnpm run test:e2e # server + browser e2e tests
pnpm run test:all # everything
License
Licensed under the Apache 2.0 License, Copyright © 2018 Scott Taylor
관련 프로젝트 살펴보기
freeCodeCamp/freeCodeCamp
freeCodeCamp.org의 오픈 소스 코드베이스와 커리큘럼입니다. 수학, 프로그래밍, 컴퓨터 과학을 무료로 배울 수 있습니다.
459,081 스타donnemartin/system-design-primer
대규모 시스템 설계 방법을 배우고 시스템 설계 면접을 준비할 수 있습니다. Anki 플래시카드가 포함되어 있습니다.
377,757 스타react/react
웹과 네이티브 사용자 인터페이스를 위한 라이브러리.
252,574 스타vuejs/vue
Vue 2 저장소입니다. Vue 3은 https://github.com/vuejs/core를 방문하세요.
212,526 스타