Giter Site home page Giter Site logo

Comments (5)

snow01 avatar snow01 commented on May 20, 2024 1

Above questions show a very fundamental confusion about working of react-helmet. Let me try explain here --

  1. link, meta all reside in head section of the HTML page, while displayable content resides in body section of the page.
  2. We do not want to (or probably we can not) control head section of the page through react.
  3. And in a single page application - we have only single opportunity to generate head section -- the time when we load the page from server.
  4. But even in single page application we want to have a different title, meta tags (specially for integration with FB, Twitter etc). Say you have products on your site - for each product page you would want to have different title. Doing this in single page app is tough.
  5. But in a fully structured system, we may not have a single place where we can define all meta information. In some cases, title may be coming from component A (say VideoCard component), in another case from component B (say ArticleCard component). That is decision for what meta tags should be there in page is not at single place, but it is distributed into multiple components.

What is the reason/use case for having the render() method only render this.props.children?
if there is > 1 prop, render those props as elements (something) within a span or head element.

  1. You can assume react-helmet as a collector of properties. Through <Helmet meta={}/> you do not intend to render anything - but want to collect all the meta properties seen in the entire render cycle. You define meta tags at the most appropriate component, wherever data is available. There can be multiple components defining <Helmet .../> - at the end of the render cycle, Helmet component collects all property types and attaches them into head section. That's the exact purpose of react-helmet - to be able to generate meta tags.

Why does the server usage example use Helmet.constructor.rewind()?

  1. For isomorphic applications, when you generate page at server side - React provides you only one way to get the output - as string. But during that renderToString process a side effect has run - side-effect of collecting all meta tags. You access all meta tags object through rewind() - rewind() is used for two purposes: (a) to give you all properties collected, which you can write into a page through jade or something (b) cleanup all the memory it would have created to collect these meta tags.

from react-helmet.

KATT avatar KATT commented on May 20, 2024 1

This is what I just made up to solve the server-side problem in my fluxible app

debug('Rendering Application component into html');
let html = React.renderToStaticMarkup(htmlComponent({
    context: context.getComponentContext(),
    state  : exposed,
    markup : React.renderToString(context.createElement())
}));
// Get head tags from Helmet
let headMap = Helmet.rewind();

// Make sure they are all HTML
headMap.title = `<title>${headMap.title}</title>`;

// Get all dem HTML tags
let headHtml = Object.values(headMap).join('\n');

debug(`<head> inject from Helmet:\n${headHtml}`);
headHtml = headHtml.replace(/(\r\n|\n|\r)/gm, '');

// inject them in the HTML
html = html.replace('</head>', `${headHtml}</head>`);



debug('Sending markup');
res.type('html');
res.write('<!DOCTYPE html>' + html);
res.end();

from react-helmet.

snow01 avatar snow01 commented on May 20, 2024

Fixed this issue here and submitted a pull request - #2

My branch till then - https://github.com/snow01/react-helmet.git

Thanks!

from react-helmet.

choonkending avatar choonkending commented on May 20, 2024

Thanks @snow01! I gave it a shot and now running Helmet.rewind() gives me an object that I can use to render on the server side. Hopefully it gets merged!

I went through Helmet.jsx and have a couple of questions in general.

  1. What is the reason/use case for having the render() method only render this.props.children?

       // render in Helmet.jsx 
       render() {
            if (Object.is(React.Children.count(this.props.children), 1)) {
                return React.Children.only(this.props.children);
            } else if (React.Children.count(this.props.children) > 1) {
                return (
                    <span>
                        {this.props.children}
                    </span>
                );
            }
    
            return null;
        }

    My initial expectation for the render method was:

    • if there is > 1 prop, render those props as elements (something) within a span or head element.

      <Helmet
          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"}
          ]}
      />
      
      /* 
      * Expected renderToString() behavior
      */
      <head>
          <link rel="apple-touch-icon" href="http://mysite.com/img/apple-touch-icon-57x57.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://mysite.com/img/apple-touch-icon-72x72.png" />
      </head>
      
      /* 
      * Actual renderToString() behavior
      */
      <noscript data-reactid=".tqn1t74i68" data-react-checksum="-1541140300"></noscript>
    • The current behaviour of render() (Correct me if I'm wrong) :

      class Header extends React.Component {
        render() {
          return (
            <Helmet>
              <link rel="stylesheet" href="yoyo" />
              <link rel="stylesheet" href="yaya" />
            </Helmet>
          );
        }
      }
      
      let header = React.renderToString(<Header />);
      /*
      * header evaluates to
      */
      <span data-reactid=".jris83nif4" data-react-checksum="524499219">
         <link rel="stylesheet" href="yoyo" data-reactid=".jris83nif4.0">
         <link rel="stylesheet" href="yaya" data-reactid=".jris83nif4.1">
      </span>

      In the examples section, it was not immediately apparent why we should use rewind() instead of using React.renderToString(). That was my source of confusion. Perhaps provide more examples for server side usage?

  2. Why does the server usage example use Helmet.constructor.rewind()?

The code here shows that it's a static method. :)

from react-helmet.

choonkending avatar choonkending commented on May 20, 2024

@snow01
Thanks for clearing that up.

link, meta all reside in head section of the HTML page, while displayable content resides in body section of the page.

Haha thanks I know this part.

You can assume react-helmet as a collector of properties. Through you do not intend to render anything - but want to collect all the meta properties seen in the entire render cycle. You define meta tags at the most appropriate component, wherever data is available. There can be multiple components defining - at the end of the render cycle, Helmet component collects all property types and attaches them into head section. That's the exact purpose of react-helmet - to be able to generate meta tags.

This was a very good explanation.

@KATT

I had a similar idea for my isomorphic alt app. I've been using webpack's html-loader for rendering the html on a branch currently and been experimenting with react-helmet.

The idea is to render the main app and the head section with webpack as 2 separate entry points (from the server), and replacing the content on a response much like yours. Thanks.

from react-helmet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.