iansinnott / react-static-webpack-plugin

Build full static sites using React, React Router and Webpack (Webpack 2 supported)
MIT License
155 stars 24 forks source link

Meta tags #12

Open glennreyes opened 8 years ago

glennreyes commented 8 years ago

Is there a way to generate different meta tags (title, description) for each route? Something like how the titles work.

I've tried adding like react-helmet or react-document-meta but without success 😐. They work on client-side but the build remains without changes. At the moment I'm using the title prop to generate specific page data.

iansinnott commented 8 years ago

Good point @glennreyes. Do you have any thoughts on what a good API might be? Maybe pass relevant rendering information to the JSX template as props? I definitely want this to be more extensible out of the box.

glennreyes commented 8 years ago

Do you have any thoughts on what a good API might be? Maybe pass relevant rendering information to the JSX template as props?

I've thought like passing another prop to the route like:

<Route meta={{ title: 'Your title', description: 'Your description' }} title="Your page title" />

So your template could look like:

const Template = ({ meta, title }) => (
  <html>
    <head>
      <title>{title}</title>
      <meta property="og:title" content={meta.title} />
      <meta property="og:description" content={meta.description} />
    </head>
  </html>
);

What do you think?

iansinnott commented 8 years ago

Yeah that sounds good to me 👍 . I think I'd like to generalize it and allow the passing of any router props to the template.

lifeiscontent commented 7 years ago

@iansinnott any updates on getting this working?

iansinnott commented 7 years ago

@lifeiscontent nope. I haven't been putting much time towards improvements in this project lately since it depends heavily on both Webpack and React Router, both of which will (supposedly) see new major version releases in the near future.

So I've been loth to implement new stuff until the RR v4 and Webpack v2 APIs are settled, but I would certainly welcome a PR if you want to implement meta tags :)

thebrengun commented 7 years ago

I'm using React Helmet and would like to use it as described in the docs using Helmet.renderStatic() (formerly rewind()). My thought is that it could be called right after const body = component ? renderMethod(component) : ''; and the instance could be passed into the template as helmet.

Then any relevant tags or attributes can be added to the template in the manner demonstrated in the docs: https://github.com/nfl/react-helmet#server-usage

I'm happy to work on this but I'm unsure of the best way to do this as not everyone uses Helmet of course. Would it be passed in as another plugin? Or included in this plugin and enabled via an option flag?

I've tried calling Helmet.renderStatic() inside the template function but it throws an error and I'm guessing that maybe this in because it has to be called immediately after the render method.

iansinnott commented 7 years ago

@thebrengun hm, yeah this is still an open question. It seems like it would be helpful to have the helmet instance available to the template function.

The problem with this issue is still as you said, not everyone uses Helmet or any other particular library so there really needs to be a way to extend the plugin so anyone can add the specific functionality they need. If you have any thoughts on what that should look like let me know.

Maybe some sort of pre and post render hooks where you could call your own code, like Helmet.renderStatic()?

The stack trace that is getting thrown might also give you more insight into why it's breaking in your implementation. You can run your build command prefixed with DEBUG=react-static-webpack-plugin* to get some pretty verbose debug output about the rendering process of this plugin.