Giter VIP home page Giter VIP logo

react-meta-tags's Introduction

react-meta-tags

Handle document meta/head tags in isomorphic react with ease.

Handling title and meta/head tags in a isomporhic react is tricky. Its declarative to define those tags within the component, but they need to be moved on document head on client side as well as server side. While there are other modules which helps with the use-case like react-helmet and react-document-meta, but they require to define those tags in a object literal. react-meta-tags allow you to write those tags in a declarative way and in normal jsx format.

Install

Through npm npm install react-meta-tags --save

Or get compiled development and production version from ./dist

Usage

Using MetaTag Component

import React from 'react';
import MetaTags from 'react-meta-tags';

class Component1 extends React.Component {
  render() {
    return (
        <div className="wrapper">
          <MetaTags>
            <title>Page 1</title>
            <meta name="description" content="Some description." />
            <meta property="og:title" content="MyApp" />
            <meta property="og:image" content="path/to/image.jpg" />
          </MetaTags>
          <div className="content"> Some Content </div>
        </div>
      )
  }
}

Note : Define id on tags so if you navigate to other page, older meta tags will be removed and replaced by new ones.

ReactTitle Component

If you just want to add title on a page you can use ReactTitle instead.

import React from 'react';
import {ReactTitle} from 'react-meta-tags';

class Component2 extends React.Component {
  render() {
    return (
        <div className="wrapper">
          <ReactTitle title="Page 2"/>
          <div className="content"> Some Content </div>
        </div>
      )
  }
}

Server Usage Example

import MetaTagsServer from 'react-meta-tags/server';
import {MetaTagsContext} from 'react-meta-tags';
/** Import other required modules **/

/*
------
  some serve specific code
------
*/

app.use((req, res) => {
  //make sure you get a new metatags instance for each request
  const metaTagsInstance = MetaTagsServer();

  //react router match
  match({
    routes, location: req.url
  }, (error, redirectLocation, renderProps) => {
    let reactString;

    try{
      reactString = ReactDomServer.renderToString(
      <Provider store={store}> {/*** If you are using redux ***/}
      {/* You have to pass extract method through MetaTagsContext so it can catch meta tags */}
        <MetaTagsContext extract = {metaTagsInstance.extract}>
          <RouterContext {...renderProps}/>
        </MetaTagsContext>
      </Provider>
      );
    }
    catch(e){
      res.status(500).send(e.stack);
      return;
    }

    //get all title and metatags as string
    const meta = metaTagsInstance.renderToString();

    //append metatag string to your layout
    const htmlStr = (`
      <!doctype html>
      <html lang="en-us">
        <head>
          <meta charSet="utf-8"/>
          ${meta}
        </head>
        <body>
          <div id="content">
            ${reactString}
          </div>
        </body>
      </html>  
    `);

    res.status(200).send(layout);
  });
});

So as per above code we have to do following for server rendering

  1. Import MetaTagsServer and MetaTagsContext
  2. Create a new instance of MetaTagsServer
  3. Wrap your component inside MetaTagsContext and pass extract method as props
  4. Extract meta string using renderToString of MetaTagsServer instance
  5. Append meta string to your html template.

JSX Layout

You might also be using React to define your layout, in which case you can use getTags method from metaTagsInstance. The layout part of above server side example will look like this.

//get all title and metatags as React elements
const metaTags = metaTagsInstance.getTags();

//append metatag string to your layout
const layout = (
  <html lang="en-us">
    <head>
      <meta charSet="utf-8"/>
      {metaTags}
    </head>
    <body>
      <div id="app" dangerouslySetInnerHTML={{__html: reactString}} />
    </body>
  </html>  
);

const htmlStr = ReactDomServer.renderToString(layout);

res.status(200).send(htmlStr);

Meta Tag Uniqueness

  • The module uniquely identifies meta tag by id / property / name / itemProp attribute.
  • Multiple meta tags with same property / name is valid in html. If you need such case. Define a different id to both so that it can be uniquely differentiate.
  • You should give an id if meta key is different then property/name/itemProp to uniquely identify them.

react-meta-tags's People

Contributors

alex-shul avatar chrisdoc avatar dependabot[bot] avatar jbonez87 avatar kaushiknishchay avatar madkatze avatar s-yadav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-meta-tags's Issues

Error

'MetaTags' cannot be used as a JSX component.
Its instance type 'Meta' is not a valid JSX element.
The types returned by 'render()' are incompatible between these types.
Type 'React.ReactNode' is not assignable to type 'import("/node_modules/@types/react-transition-group/node_modules/@types/react/index").ReactNode'.
Type '{}' is not assignable to type 'ReactNode'. TS2786

Uncaught TypeError: cannot read property 'children' of null

For line 109 in lib/meta_tags.js :-
var childNodes = Array.prototype.slice.call(_this.temporaryElement.querySelector('.react-head-temp').children);

I am getting Cannot read property 'children' of null. This line also needs to be handled ?

Is it because I did not use id in metatags as you had mentioned in Note : Define id on tags so if you navigate to other page, older meta tags will be removed and replaced by new ones.

this error comes when i update the description or title of the page. In that case, should i use id as like :-
<title id="title-tag">{this.props.title}</title>

Originally posted by @AakashGfude in #25 (comment)

match is not defined

the match is not defined ...I got this error wan run server
Where get match function, how to solve this problem??

Script tag JSON-LD render twice!

I have included the in my JSX. Why does my script tag render twice?

the first script tag returns undifined values, and the second one returns the correct values, i have added async & defer to my script tag but in vain!!

<MetaTags>
            <script type="application/ld+json">
            {`
              {
                "@context": "https://schema.org/",
                "@type": "CreativeWorkSeries",
                "name": "${this.state.name}",
                "aggregateRating": {
                  "@type": "AggregateRating",
                  "ratingValue": "${this.state.rating}",
                  "bestRating": "5",
                  "ratingCount": "${this.state.count}"
                }
              }
            `}
            </script>
</MetaTags>

Whatsapp share og:image not working

Hello,

I have a page in my react project that I want to render a dynamic favicon, and also when share it, it will display that dynamic icon (like Whatsapp, Facebook etc., and those things can be done by dynamic meta tag with og:image propery).

When I share the page with react-meta-tags, although that in my source I can see that og:image was updated to the dynamic image I want to, whenever I send link to the website I get the original (In Index.html) og:image shown, and if I don't have original og:image in my Index.html page, than the website original favicon is displays instead.

For an example, The website original og:image content is the image with "Zedka" write in it (As in the following image).
image

And just if you want to see the source head tags so they are really correct:
https://bucard.co.il/digitalCard/Github-ZCA

  • I just want that the eye icon for example in this page will be the share image in the social media *

Please anyone can help me? What's the problem here?

Provide a renderToComponents functionality

Hi there, I tried a few libraries to manage the head section with SSR and this library turns out to be the best one for my use case.
The problem I am facing is that I do not have a template string like you have in your example on the server side. I have a react component like so:

    const markup = ReactDOMServer.renderToString(rootComponent);
    const meta = metaTagsInstance.renderToString();
    console.log(meta);
    const state = store.getState();
    const html = ReactDOMServer.renderToStaticMarkup(
      <Html
        PROD={PROD}
        assets={assets}
        meta={meta}
        markup={markup}
        state={state}
        splitPoints={context.splitPoints}
        localeData={localeData[locale]}
      />
    );
    const doctype = "<!DOCTYPE html>";
    res.send(doctype + html);

This is a problem because now the meta string is pass down the Html component but I can not insert this string without englobing them (like the markup string enblobed in the root div):

          <div id="root" dangerouslySetInnerHTML={{__html: markup}} />

If react-meta-tags could return an array of React component, then I could just insert this array like so:

<head>
  {arrayOfMeta}
  ...
</head>

How much work do you think it is to implement this feature in react-meta-tags ? Do you have any idea if this is easy or difficult to do?

Add support for React 17

~/repos/example (master) % npm install react-meta-tags --save                                                                                                                           15:17:21
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^17.0.1" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.6.0" from [email protected]
npm ERR! node_modules/react-meta-tags
npm ERR!   react-meta-tags@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Duplicate title and meta tags - client side rendering

The app renders a div with the title and meta tags thrice on client side.

react-devtool log

<divclassName="react-head-temp">

<title>Samhita GoodCSR | CSR in a box</title> <title>Marketplace - GoodCSR</title> <title>Samhita GoodCSR | CSR in a box</title> <title>Samhita GoodCSR | CSR in a box</title> <title>Marketplace - GoodCSR</title> <title>Marketplace - GoodCSR</title> <title>Marketplace - GoodCSR</title>

Duplicate meta tags when server-side rendering

Hi! Thank you for this awesome package, it is extremely helpful! I've encountered one issue though.

When I'm using it for server-side rendering, it seems like it's duplicating the meta info. I render it as html and insert it on server, but then when react loads on the frontend, it inserts them again.

Can you help me to figure out how I can prevent this?

Example generates warning

Hi, on your readme, the example says <div class="wrapper">, but shouldn't it be <div className="wrapper"> instead? Happy to provide a PR if so.

Thanks!

Getting DOMException while using dynamic tags.

I'm trying to use my Meta Tags component based on props. But it is giving me the following exception.

6.app.eaf800e13c4a4772da08.js:1 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
    at t.removeChild (https://www.mobilelive.ca/2.app.cbc7ee4c9ab4bb71272f.js:1:7320)
    at Array.forEach (<anonymous>)
    at HTMLDivElement.<anonymous> 

Seeting for Google+, microformats Schema.org duplicate when there is a rerender

When there is first render we have:

<title>Sites's title</title>
<meta itemprop="name" content="Site's name"/>

But when there is second render we have (first meta tag did'n remove):

<meta itemprop="name" content="Site's name"/>
<title>Sites's title 2</title>
<meta itemprop="name" content="Site's name 2"/>

My render function:

render(){
   const {title} = this.props;
    return (
        <MetaTags>
            {!!title && (
                <React.Fragment>
                    <title>{title}</title>
                    <meta itemProp="name" content={title}/>
                </React.Fragment>
            )}
        </MetaTags>
    );
}

Update existing tags

I'd like this package to parse the DOM looking for existing tags, and if they exist, they should overwrite them instead of add new ones. If I set a <title /> tag in my HTML, and then try to override it with this package, it doesn't get updated because the browser only uses the first <title /> tag it sees.

This would also let us get rid of the ids that's currently in use.

Using with renderToNodeStream

Is there any way to use react-meta-tags with renderToNodeStream? In this case, I need to generate meta tags before rendering app.
I didn't find any examples in the documentation.

MetaTags in TypeScript

How do i implement this in .net core with typescript ? i cant import since it has an any type and if i require it it only gives me an error that is does not have a call signature or construct.

React.PropTypes depreciated, use prop-types module instead.

The console outputs a warning when using the latest version of react (15.5.4):

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

This is due to the depreciation of using react.proptypes. The new recommended approach is to use the seperate prop-types node module.

These aren't indexed by Google

I did a test using Google Search Console to see how Googlebot crawls pages Node/React pages with these meta tags ... they don't work at all.

So this package is sort of useless ...

Removing babel-runtime from the bundle

I was about to consider react-meta-tags but it is including babel-runtime in my client bundle and this is pretty bad.
Why do you need babel runtime in your final bundler by the way?
I am pretty sure this is inserted because of some babel plugins that you use
"plugins": ["transform-runtime", "transform-class-properties", "transform-object-rest-spread"]
Or the preset: es-2015 I am not sure.

I do not have this issue with I use the preset: env instead of those plugins
"presets": ["react", "env", "stage-0"]

If you wanted to investigate this issue I recommend using the webpack-bundle-analyzer to check the bundle size and content.
Thanks

re: Define id on tags so if you navigate to other page, older meta tags will be removed and replaced by new ones.

Hi,

First thank you for providing this meta tag module. I am probably one of several people trying to implement SEO-friendly pre-rendered React to serve from static hosting.

By the

Note: Define id on tags so if you navigate to other page, older meta tags will be removed and replaced by new ones.

should I add identical id's to tags that should be replaced?
For instance if I have the following in my index.html

<meta id="og-title-meta-tags" property="og:title" content="original title" />

Would I have the following in a index.js file?

<meta id="og-title-meta-tags" property="og:title" content="new title" />

Also an off topic question - are all tags that can be used in possible to be used?
i.e.) etc.?

Thank you for your reply.

React v18 support

Hi there, got any plans to support React v18?

I noticed an error when using React Strict Mode

Screen Shot 2022-01-19 at 10 35 59 AM

e

Meta tags string rendered by server has a trailing slash

Wanted:
<meta name="some-name" content="Some content.">
Rendered:
<meta name="some-name" content="Some content." />

Code to reproduce:

npm init --yes
npm install babel-cli babel-preset-react react react-dom react-meta-tags
$(npm bin)/babel-node --presets react index.js
// index.js
const React = require("react");
const { MetaTags } = require("react-meta-tags");

function Component1() {
  return (
    <div>
      <MetaTags>
        <title>Page 1</title>
        <meta name="some-name" content="Some content." />
      </MetaTags>
      <div>Some Content</div>
    </div>
  );
}

const MetaTagsServer = require("react-meta-tags/server");
const { MetaTagsContext } = require("react-meta-tags");
const ReactDOMServer = require("react-dom/server");

const metaTagsInstance = MetaTagsServer();

const element = (
  <MetaTagsContext extract={metaTagsInstance.extract}>
    <Component1 />
  </MetaTagsContext>
);

ReactDOMServer.renderToString(element);

console.log(metaTagsInstance.renderToString());

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.