Have ideas to improve npm?Join in the discussion! »

    react-helmet-async
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.2 • Public • Published

    react-helmet-async

    CircleCI

    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.

    Usage

    New is 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 ReactDOM from 'react-dom';
    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>
    );
     
    ReactDOM.hydrate(
      app,
      document.getElementById(‘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…

    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);

    License

    Licensed under the Apache 2.0 License, Copyright © 2018 Scott Taylor

    Keywords

    none

    Install

    npm i [email protected]

    Version

    1.0.2

    License

    Apache-2.0

    Unpacked Size

    216 kB

    Total Files

    17

    Last publish

    Collaborators

    • avatar