{"_id":"react-native-helmet-async","_rev":"4-f49ca1691c4828aaefe06ce691abe31c","name":"react-native-helmet-async","dist-tags":{"latest":"2.0.4"},"versions":{"2.0.4":{"name":"react-native-helmet-async","version":"2.0.4","author":{"name":"Scott Taylor","email":"scott.c.taylor@mac.com"},"license":"Apache-2.0","_id":"react-native-helmet-async@2.0.4","maintainers":[{"name":"bycedric","email":"me@bycedric.com"}],"homepage":"https://github.com/staylor/react-helmet-async#readme","bugs":{"url":"https://github.com/staylor/react-helmet-async/issues"},"dist":{"shasum":"93f53a1ff22d6898039688a541653a2d6b6866bb","tarball":"https://registry.npmjs.org/react-native-helmet-async/-/react-native-helmet-async-2.0.4.tgz","fileCount":14,"integrity":"sha512-m3CkXWss6B1dd6mCMleLpzDCJJGGaHOLQsUzZv8kAASJmMfmVT4d2fx375iXKTRWT25ThBfae3dECuX5cq/8hg==","signatures":[{"sig":"MEQCIDshFD4MsBcGVz9i65V5CeS97usC8JaasM2yC5SrYXozAiBaCJNocu1W8/TYBIRoZNYOfDtCIgYw/3+5jas2K5qnbA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86590},"main":"./lib/index.js","module":"./lib/index.esm.js","gitHead":"556fed1631f9658e8821f22ef1936a854cc74446","scripts":{"lint":"eslint --cache --cache-location ./node_modules/.cache/eslint --report-unused-disable-directives .","test":"vitest run","clean":"rimraf lib","types":"tsc src/index.tsx --jsx react --declaration --esModuleInterop --allowJs --emitDeclarationOnly --outDir lib","compile":"yarn run clean && NODE_ENV=production tsx build.ts && yarn types","prepare":"yarn compile && husky install","lint-fix":"yarn lint --fix","test-watch":"yarn test --watch","test-update":"yarn test -u"},"typings":"./lib/index.d.ts","_npmUser":{"name":"bycedric","email":"me@bycedric.com"},"repository":{"url":"git+ssh://git@github.com/staylor/react-helmet-async.git","type":"git"},"_npmVersion":"10.5.0","description":"React Native fork of thread-safe Helmet for React 16+ and friends","directories":{},"sideEffects":false,"_nodeVersion":"20.12.0","dependencies":{"invariant":"^2.2.4","shallowequal":"^1.1.0","react-fast-compare":"^3.2.2"},"_hasShrinkwrap":false,"devDependencies":{"raf":"3.4.1","tsx":"4.6.1","vite":"4.5.0","husky":"8.0.3","jsdom":"22.1.0","react":"18.2.0","eslint":"8.54.0","rimraf":"5.0.5","vitest":"0.34.6","esbuild":"0.19.8","prettier":"3.1.0","react-dom":"18.2.0","typescript":"5.2.2","@types/jsdom":"21.1.6","@types/react":"18.2.39","@types/eslint":"8.44.8","@commitlint/cli":"18.4.3","@types/invariant":"2.2.37","@types/shallowequal":"1.1.5","@vitejs/plugin-react":"4.2.0","@testing-library/react":"14.1.2","eslint-config-prettier":"9.0.0","eslint-plugin-prettier":"5.0.1","@remix-run/eslint-config":"2.3.1","@testing-library/jest-dom":"6.1.5","@commitlint/config-conventional":"18.4.3"},"peerDependencies":{"react":"^16.6.0 || ^17.0.0 || ^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/react-native-helmet-async_2.0.4_1714424075728_0.7994206006689235","host":"s3://npm-registry-packages"}}},"time":{"created":"2024-04-29T20:54:35.727Z","modified":"2024-10-14T15:43:24.997Z","2.0.4":"2024-04-29T20:54:35.915Z"},"bugs":{"url":"https://github.com/staylor/react-helmet-async/issues"},"author":{"name":"Scott Taylor","email":"scott.c.taylor@mac.com"},"license":"Apache-2.0","homepage":"https://github.com/staylor/react-helmet-async#readme","repository":{"url":"git+ssh://git@github.com/staylor/react-helmet-async.git","type":"git"},"description":"React Native fork of thread-safe Helmet for React 16+ and friends","maintainers":[{"name":"bycedric","email":"me@bycedric.com"}],"readme":"# react-helmet-async\n\n[![CircleCI](https://circleci.com/gh/staylor/react-helmet-async.svg?style=svg)](https://circleci.com/gh/staylor/react-helmet-async)\n\n[Announcement post on Times Open blog](https://open.nytimes.com/the-future-of-meta-tag-management-for-modern-react-development-ec26a7dc9183)\n\nThis package is a fork of [React Helmet Async](https://github.com/staylor/react-helmet-async), which is a fork of [React Helmet](https://github.com/nfl/react-helmet).\nIt's a version of React Helmet Async without the peer dependency to `react-dom`, [see this issue](https://github.com/staylor/react-helmet-async/pull/224).\n`<Helmet>` usage is synonymous, but server and client now requires `<HelmetProvider>` to encapsulate state per request.\n\n`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.\n\n## Usage\n\n**New is 1.0.0:** No more default export! `import { Helmet } from 'react-helmet-async'`\n\nThe 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:\n\n```javascript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\n\nconst app = (\n  <HelmetProvider>\n    <App>\n      <Helmet>\n        <title>Hello World</title>\n        <link rel=\"canonical\" href=\"https://www.tacobell.com/\" />\n      </Helmet>\n      <h1>Hello World</h1>\n    </App>\n  </HelmetProvider>\n);\n\nReactDOM.hydrate(\n  app,\n  document.getElementById(‘app’)\n);\n```\n\nOn the server, we will no longer use static methods to extract state. `react-side-effect`\nexposed a `.rewind()` method, which Helmet used when calling `Helmet.renderStatic()`. Instead, we are going\nto pass a `context` prop to `HelmetProvider`, which will hold our state specific to each request.\n\n```javascript\nimport React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\n\nconst helmetContext = {};\n\nconst app = (\n  <HelmetProvider context={helmetContext}>\n    <App>\n      <Helmet>\n        <title>Hello World</title>\n        <link rel=\"canonical\" href=\"https://www.tacobell.com/\" />\n      </Helmet>\n      <h1>Hello World</h1>\n    </App>\n  </HelmetProvider>\n);\n\nconst html = renderToString(app);\n\nconst { helmet } = helmetContext;\n\n// helmet.title.toString() etc…\n```\n\n## Streams\n\nThis package only works with streaming if your `<head>` data is output outside of `renderToNodeStream()`.\nThis is possible if your data hydration method already parses your React tree. Example:\n\n```javascript\nimport through from 'through';\nimport { renderToNodeStream } from 'react-dom/server';\nimport { getDataFromTree } from 'react-apollo';\nimport { Helmet, HelmetProvider } from 'react-helmet-async';\nimport template from 'server/template';\n\nconst helmetContext = {};\n\nconst app = (\n  <HelmetProvider context={helmetContext}>\n    <App>\n      <Helmet>\n        <title>Hello World</title>\n        <link rel=\"canonical\" href=\"https://www.tacobell.com/\" />\n      </Helmet>\n      <h1>Hello World</h1>\n    </App>\n  </HelmetProvider>\n);\n\nawait getDataFromTree(app);\n\nconst [header, footer] = template({\n  helmet: helmetContext.helmet,\n});\n\nres.status(200);\nres.write(header);\nrenderToNodeStream(app)\n  .pipe(\n    through(\n      function write(data) {\n        this.queue(data);\n      },\n      function end() {\n        this.queue(footer);\n        this.queue(null);\n      }\n    )\n  )\n  .pipe(res);\n```\n\n## Usage in Jest\nWhile 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.\n\n```javascript\nimport { HelmetProvider } from 'react-helmet-async';\n\nHelmetProvider.canUseDOM = false;\n```\n\n## Prioritizing tags for SEO\n\nIt 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.\n\nIn the component:\n```javascript\n<Helmet prioritizeSeoTags>\n  <title>A fancy webpage</title>\n  <link rel=\"notImportant\" href=\"https://www.chipotle.com\" />\n  <meta name=\"whatever\" value=\"notImportant\" />\n  <link rel=\"canonical\" href=\"https://www.tacobell.com\" />\n  <meta property=\"og:title\" content=\"A very important title\"/>\n</Helmet>\n```\n\nIn your server template:\n\n```javascript\n<html>\n  <head>\n    ${helmet.title.toString()}\n    ${helmet.priority.toString()}\n    ${helmet.meta.toString()}\n    ${helmet.link.toString()}\n    ${helmet.script.toString()}\n  </head>\n  ...\n</html>\n```\n\nWill result in:\n\n```html\n<html>\n  <head>\n    <title>A fancy webpage</title>\n    <meta property=\"og:title\" content=\"A very important title\"/>\n    <link rel=\"canonical\" href=\"https://www.tacobell.com\" />\n    <meta name=\"whatever\" value=\"notImportant\" />\n    <link rel=\"notImportant\" href=\"https://www.chipotle.com\" />\n  </head>\n  ...\n</html>\n```\n\nA list of prioritized tags and attributes can be found in [constants.js](./src/constants.js).\n\n## Usage without Context\nYou can optionally use `<Helmet>` outside a context by manually creating a stateful `HelmetData` instance, and passing that stateful object to each `<Helmet>` instance:\n\n\n```js\nimport React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { Helmet, HelmetProvider, HelmetData } from 'react-helmet-async';\n\nconst helmetData = new HelmetData({});\n\nconst app = (\n    <App>\n      <Helmet helmetData={helmetData}>\n        <title>Hello World</title>\n        <link rel=\"canonical\" href=\"https://www.tacobell.com/\" />\n      </Helmet>\n      <h1>Hello World</h1>\n    </App>\n);\n\nconst html = renderToString(app);\n\nconst { helmet } = helmetData.context;\n```\n\n## License\n\nLicensed under the Apache 2.0 License, Copyright © 2018 Scott Taylor\n","readmeFilename":"README.md"}