├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .flowconfig
├── .gitignore
├── .prettierignore
├── .size-snapshot.json
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── babel.config.js
├── example
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── app.html
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── Contact.css
│ ├── Contact.js
│ ├── Footer.css
│ ├── Footer.js
│ ├── Home.css
│ ├── Home.js
│ ├── client.js
│ ├── client
│ ├── index.css
│ └── index.js
│ ├── index.js
│ ├── logo.svg
│ └── server
│ ├── index.js
│ └── middleware
│ ├── html.js
│ └── render.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
├── HeadProvider.js
├── HeadTag.js
├── context.js
├── index.d.ts
├── index.js
├── index.js.flow
└── test_flow.js
└── tests
├── ReactDOMMock.js
├── __snapshots__
├── dom.test.js.snap
├── ssr.test.js.snap
└── web.test.js.snap
├── dom.test.js
├── ssr.test.js
└── web.test.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = tabs
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.{json,yml,md,babelrc,eslintrc,remarkrc}]
12 | indent_style = space
13 | indent_size = 2
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | test_flow.js
2 | package.json
3 | package-lock.json
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: 'babel-eslint',
3 | plugins: ['prettier'],
4 | extends: ['airbnb', 'prettier', 'prettier/react'],
5 | env: {
6 | browser: true,
7 | jest: true,
8 | },
9 | rules: {
10 | 'global-require': 0,
11 | 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
12 | 'react/forbid-prop-types': 0,
13 | 'react/prop-types': 0,
14 | 'react/no-did-mount-set-state': 0,
15 | 'react/sort-comp': 0,
16 | 'react/no-unused-state': 0,
17 | 'react/require-default-props': 0,
18 | 'react/state-in-constructor': [0, 'never'],
19 | 'react/jsx-props-no-spreading': 0,
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 |
3 | [include]
4 |
5 | [libs]
6 |
7 | [lints]
8 |
9 | [options]
10 |
11 | [strict]
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | dist
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 |
11 | # Runtime data
12 | pids
13 | *.pid
14 | *.seed
15 | *.pid.lock
16 |
17 | # Directory for instrumented libs generated by jscoverage/JSCover
18 | lib-cov
19 |
20 | # Coverage directory used by tools like istanbul
21 | coverage
22 |
23 | # nyc test coverage
24 | .nyc_output
25 |
26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
27 | .grunt
28 |
29 | # Bower dependency directory (https://bower.io/)
30 | bower_components
31 |
32 | # node-waf configuration
33 | .lock-wscript
34 |
35 | # Compiled binary addons (http://nodejs.org/api/addons.html)
36 | build/Release
37 |
38 | # Dependency directories
39 | node_modules/
40 | jspm_packages/
41 |
42 | # Typescript v1 declaration files
43 | typings/
44 |
45 | # Optional npm cache directory
46 | .npm
47 |
48 | # Optional eslint cache
49 | .eslintcache
50 |
51 | # Optional REPL history
52 | .node_repl_history
53 |
54 | # Output of 'npm pack'
55 | *.tgz
56 |
57 | # Yarn Integrity file
58 | .yarn-integrity
59 |
60 | # dotenv environment variables file
61 | .env
62 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package*.json
2 |
--------------------------------------------------------------------------------
/.size-snapshot.json:
--------------------------------------------------------------------------------
1 | {
2 | "index.umd.js": {
3 | "bundled": 8382,
4 | "minified": 3575,
5 | "gzipped": 1446
6 | },
7 | "index.min.js": {
8 | "bundled": 8382,
9 | "minified": 3575,
10 | "gzipped": 1446
11 | },
12 | "index.cjs.js": {
13 | "bundled": 7477,
14 | "minified": 4049,
15 | "gzipped": 1337
16 | },
17 | "index.esm.js": {
18 | "bundled": 6593,
19 | "minified": 3316,
20 | "gzipped": 1188,
21 | "treeshaked": {
22 | "rollup": {
23 | "code": 305,
24 | "import_statements": 269
25 | },
26 | "webpack": {
27 | "code": 1549
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 10
4 | - 12
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | First, thank you for contributing! 🎉
4 |
5 | The local development workflow is fairly straightfowrad:
6 |
7 | 1. Fork the repo and then git clone your fork locally (be sure to work on a new branch, not on your `master` branch)
8 | 1. `npm install`
9 | 1. `npm run dev` this will start the source build watcher and install/start the example app for you
10 | 1. Then you can view the example app running at http://localhost:3000. Changes you make to the source will compile and hot-reload
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Jeremy Gayed
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-head [](https://www.npmjs.org/package/react-head) [](https://bundlephobia.com/result?p=react-head) [](CONTRIBUTING.md#pull-requests)
2 |
3 | Asynchronous SSR-ready Document Head management for React 16.3+
4 |
5 | ## Motivation
6 |
7 | This module allows you to define `document.head` tags anywhere in your component hierarchy. The motivations are similar to [react-helmet](https://github.com/nfl/react-helmet) in that you may only have the information for certain tags contextually deep in your component hiearchy. There are no dependencies (it does not use react-side-effects) and it should work fine with asynchronous rendering; the only requirement is React 16.3+.
8 |
9 | [Read more about react-head and how it works on Medium](https://jeremygayed.com/making-head-tag-management-thread-safe-with-react-head-323654170b45)
10 |
11 | ## Installation
12 |
13 | ```sh
14 | npm i react-head
15 | ```
16 |
17 | or
18 |
19 | ```sh
20 | yarn add react-head
21 | ```
22 |
23 | ## How it works
24 |
25 | 1. You wrap your App with `
` block of your server template 28 | 1. To insert head tags within your app, just render one of `
`, ``, ``, ``, and `
56 | ${renderToString(headTags)} 57 | 58 |
61 |