📜 ⬆️ ⬇️

Universal (isomorphic) “helmet” for React js or How convenient to work with head on React js

image

The nfl guys cured one of the pains of React js, working with the head. It's about the react-helmet library. It works on both the client and the server.

In the previous article, I wrote about the boiler-spit, in which react-helmet is already used, so I’ll take it:

git clone https://github.com/BoryaMogila/koa_react_redux.git; npm install; npm run-script run-with-build; 

For those who have their own assembly, put the module:

  npm install --save react-helmet 

We connect in our component:
')
 import { Component } from 'react' import Helmet from "react-helmet" class SomeComponent extends Component { render(){ return ( <div> <Helmet htmlAttributes={{"lang": "en", "amp": undefined}} // amp takes no value title="My Title" titleTemplate="MySite.com - %s" defaultTitle="My Default Title" base={{"target": "_blank", "href": "http://mysite.com/"}} meta={[ {"name": "description", "content": "Helmet application"}, {"property": "og:type", "content": "article"} ]} link={[ {"rel": "canonical", "href": "http://mysite.com/example"}, {"rel": "apple-touch-icon", "href": "http://mysite.com/img/apple-touch-icon-57x57.png"}, {"rel": "apple-touch-icon", "sizes": "72x72", "href": "http://mysite.com/img/apple-touch-icon-72x72.png"} ]} script={[ {"src": "http://include.com/pathtojs.js", "type": "text/javascript"}, {"type": "application/ld+json", innerHTML: `{ "@context": "http://schema.org" }`} ]} //  </div> ); } 

Helmet can be used in components of any degree of nesting, and the properties specified in the component below the level will grind the properties specified in the component above the level.

 class SomeComponent extends Component { render(){ return ( <div> <Helmet title="My Title" meta={[ {"name": "description", "content": "Helmet application"} ]} link={[ {"rel": "apple-touch-icon", "href": "http://mysite.com/img/apple-touch-icon-57x57.png"}, {"rel": "apple-touch-icon", "sizes": "72x72", "href": "http://mysite.com/img/apple-touch-icon-72x72.png"} ]} base={{"href": "http://mysite.com/"}} /> <AnotherComponent /> </div> ) } } class AnotherComponent extends Component { render(){ return ( <div> <Helmet title="Nested Title" meta={[ {"name": "description", "content": "Nested component"} ]} link={[ {"rel": "apple-touch-icon", "href": "http://mysite.com/img/apple-touch-icon-180x180.png"} ]} base={{"href": "http://mysite.com/blog"}} /> </div> ) } } 

As a result, we get:

 <head> <title>Nested Title</title> <meta name="description" content="Nested component"> <link rel="apple-touch-icon" href="http://mysite.com/img/apple-touch-icon-180x180.png"> <base href="http://mysite.com/blog"> </head> 

For the title there is an opportunity to set a template:

 <Helmet defaultTitle="My Site" titleTemplate="My Site - %s" /> <Helmet title="Nested Title" /> 

Result:

 <head> <title>My Site - Nested Title</title> </head> 

Creating a script tag:

 <Helmet script={[{ "type": "application/ld+json", "innerHTML": `{ "@context": "http://schema.org", "@type": "NewsArticle" }` }]} /> 

Result:

 <head> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "NewsArticle" } </script> </head> 

Creating a style tag:

 <Helmet style={[{ "cssText": ` body { background-color: green; } ` }]} /> 

Result:

 <head> <style> body { background-color: green; } </style> </head> 

To get data for head on the server, call the rewind () method after ReactDOM.renderToString or ReactDOM.renderToStaticMarkup.

The returned head object has seven possible parameters:


They have two methods toComponent () and toString ().

Converting data to a string:

 let markup = ReactDOM.renderToString(<Handler />); let head = Helmet.rewind(); const html = ` <!doctype html> <html ${head.htmlAttributes.toString()}> <head> ${head.title.toString()} ${head.meta.toString()} ${head.link.toString()} </head> <body> <div id="content"> ${markup} </div> </body> </html>` //  ctx.body = html; 

React style solution:

 let markup = ReactDOM.renderToString(<Handler />); let head = Helmet.rewind(); function HTML () { const attrs = head.htmlAttributes.toComponent(); return ( <html {...attrs}> <head> {head.title.toComponent()} {head.meta.toComponent()} {head.link.toComponent()} </head> <body> <div id="content"> // React stuff here </div> </body> </html> ); } //  ctx.body = ReactDOM.renderToString(<HTML />); 

Ready working examples for use:


PS As always glad to hear your comments and additions.

Source: https://habr.com/ru/post/311964/


All Articles