GithubHelp home page GithubHelp logo

kodyl / react-document-meta Goto Github PK

View Code? Open in Web Editor NEW
321.0 7.0 23.0 205 KB

HTML meta tags for React-based apps. Works for both client- and server-side rendering, and has a strict but flexible API.

License: MIT License

Makefile 2.52% JavaScript 96.96% HTML 0.52%

react-document-meta's Introduction

React Document Meta Build Status Coverage Status npm version

HTML meta tags for React-based apps. Works for both client- and server-side rendering, and has a strict but flexible API.

Built with React Side Effect


Installation

npm install --save react-document-meta

Note: React Side Effect requires React 0.14+ - and so does React Document Meta.

Using with React v0.13

Due to several deprecations and breaking changes to React, you'll have to use react-document-meta@^1.0.0.

Upgrading from 0.1.x to 1.x

As React Side Effect has been upgraded there is a few breaking changes, which is found in the changelog.

Features

  • Supports extending and nesting on any number of levels
  • Ability to auto generate some meta tags for open graph, twitter, and more

Usage

See example folder for a working sample.

import React from 'react';
import DocumentMeta from 'react-document-meta';

class Example extends React.Component {
  render() {
    const meta = {
      title: 'Some Meta Title',
      description: 'I am a description, and I can create multiple tags',
      canonical: 'http://example.com/path/to/page',
      meta: {
        charset: 'utf-8',
        name: {
          keywords: 'react,meta,document,html,tags'
        }
      }
    };

    return (
      <DocumentMeta {...meta}>
        <h1>Hello World!</h1>
      </DocumentMeta>
    );
  }
}

React.render(<Example />, document.getElementById('root'));

Nesting

In most real world use cases, you would like to set some defaults and modify, replace or add just some of the meta tags. react-document-meta always use the deepest data set, but you can add an extend attribute (<DocumentMeta {...metaData} extend />), to instruct the component to merge with the meta data specified one level up. You can add the extend attribute to as many DocumentMeta components you would like, but the chain needs to be complete.

Automatic Meta Tags

react-document-meta has the ability to generate meta tags based on the already provided meta data. Currently only open graph title, description and url is supported, which uses the data from title, description and canonical, and only in the case where the values has not been explicit set for og:title, og:description or og:url respectively.

Server Usage

When using react-document-meta in a project with server-side rendering, you would like to have the final meta data chunk available in your HTML output. You can achieve this by calling DocumentMeta.rewind().

Instead of getting a plain object, you can have the module return the meta as either React components or a HTML string. This is achieved by calling DocumentMeta.renderAsReact() or DocumentMeta.renderAsHTML().

import React from 'react';
import DocumentMeta from 'react-document-meta';

export default handler = (...args) => {
  ...
  const app = React.renderToString(components);
  const meta = DocumentMeta.renderAsHTML();
  const markup = `
    <html>
      <head>
        ${meta}
      </head>
      <body>
        <div id="app">
          ${app}
        </div>
      </body>
    </html>
  `
  ...
}

TODO:

  • Create full documentation
  • Improve flexibility for custom attributes

react-document-meta's People

Contributors

danieljuhl avatar gbakernet avatar markdalgleish 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  avatar  avatar  avatar

react-document-meta's Issues

Existing tags from server markup ignored, ends up with duplicate tags

I'm not sure if I'm missing something obvious here, but:

My use case is a SPA where the first rendered html from the server already contains things like title, description, canonical etc.
When my DocumentMeta enabled React app then is rendered on top, I end up with duplicate tags for all these.

Is there a way for DocumentMeta to 'hook on' to the existing tags on use those instead?
I am using react-router so when navigating the site, the second set (the duplicates) are updated correctly.

I am not using any React server side rendering. It is not an option currently (due to SEO reasons) to not have the server render these tags.

Warning: Failed propType: Invalid prop `property` supplied to `DocumentMeta`. Check the render method of `SideEffect(DocumentMeta)`.

Hi after upgrade I can see this warning:
Warning: Failed propType: Invalid prop property supplied to DocumentMeta. Check the render method of SideEffect(DocumentMeta).

I am using your component:

const basicMetadata = {
  title: 'Meetbus - Make your travels more fun',
  description: 'Explore awesome places around the world and meet other travelers',
  meta: {
    name: {
      keywords: 'traveling, exploring, wanderlust, adventure, travel, meetup, new zealand'
    },
    property: {
      'og:site_name': 'meetbus.com',
      'fb:app_id': '341640709299908',
      'fb:admins': [1107946314, 1095566451]
    }
  }
};

  render() {
        <DocumentMeta {...basicMetadata} />

Is there any problem with "property" field?

Add an option for custom attributes to link and meta tags

For example, I cannot express the following tag

<link rel="icon" type="image/png" sizes="32x32" href="/img/favicons/favicon-32x32.png">

with the structured description:

{ link: { rel: { icon: '/img/favicons/favicon-32x32.png' } } }

as it would only render as:

<link rel="icon" href="/img/favicons/favicon-32x32.png">

The internal API is operating on arrays of tags with arbitrary number of attributes, but this API is not exposed, only the nested object with a limited level of nesting can be specified.

The API i'd prefer would be as follows:

{ link: [
  { rel: 'icon', href: '/img/favicons/favicon-32x32.png', type: 'image/png', sizes: '32x32' },
  { rel: 'icon', href: '/img/favicons/favicon-16x16.png', type: 'image/png', sizes: '16x16' },
] }

What do you think?

Favicon not working when use IE

The titile is updated but favicon not display when use IE, the meta as follows:

const meta = {
      title: 'HomePage Title',
      description: 'This is the homepage title',
      link: {
        rel: { icon: '/favicon.ico' },
      },
    };

Best way to use with react-router

I'm planning to implement react-document-meta but am already using react-router. Where should I place the top-most <DocumentMeta />?

The following does not seem to work:

    <Router (..)>
        <DocumentMeta />
        <Route ... ></Route>
    </Router>

Add meta Tag dynamically

Hi,
can you please explain, how to add meta tag dynamically in server side rending. I have written something like

import React, { Component, PropTypes } from 'react'
import { defineMessages, FormattedMessage } from 'react-intl'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import DocumentMeta from 'react-document-meta';

export default class metaTag extends React.Component {
    render() {
        const meta = {
            title: 'Some Meta Title',
            description: 'I am a description, and I can create multiple tags',
            canonical: 'http://example.com/path/to/page',
            meta: {
                charSet: 'utf-8',
                name: {
                    keywords: 'react,meta,document,html,tags'
                },
                itemProp: {
                    name: 'The Name or Title Here',
                    description: 'This is the page description',
                    image: 'http://example.com/image.jpg'
                },
                property: {
                    'og:title': 'I am overriding!',
                    'og:type': 'article',
                    'og:image': 'http://example.com/image.jpg',
                    'og:site_name': 'Example Site Name',
                    'og:price:amount': '19.50',
                    'og:price:currency': 'USD',
                    'twitter:site': '@site',
                    'twitter:title': 'I am a Twitter title'
                }
            },
            auto: {
                ograph: true
            }
        };


        return (
            <div>
                <DocumentMeta {...meta} >
                <h2> Check Server side </h2>
            </div>
        );

    }
}

but how to add them to sever.js

Doesn't work with new React builds

G:\work\cinema [master +0 ~5 -0]> npm install --save [email protected]
npm WARN package.json [email protected] license should be a valid SPDX license expression
npm WARN unmet dependency G:\work\cinema\node_modules\react-intl requires react@'>=0.11.2 <1.0.0' but will load
npm WARN unmet dependency G:\work\cinema\node_modules\react,
npm WARN unmet dependency which is version 0.14.0-rc1
npm ERR! Windows_NT 6.3.9600
npm ERR! argv "C:\\Program Files\\nodejs\\\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "i
nstall" "--save" "[email protected]"
npm ERR! node v0.12.5
npm ERR! npm  v2.11.2
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@>= 0.13.0

A fix I can suggest: remove peerDependencies.

Huge dependency

I swapped from react-document-meta to react-helmet, but while doing that I noticed there appears to be something wrong with the dependencies as when I used react-document-meta my uglified production bundle size was 195 kB while after switching to react-helmet the bundle size dropped down to 65 kB. This change is the only change I made between bundles, so there are certainly some dependency issues that should be resolved. I didn't investigate what causes the issue.

doesn't work with preact-compat

Not sure if you're interested in fixing this, but since this module always requires the server-side react-dom (even on the frontend!) it doesn't work with preact (via preact-compat) since preact-compat/server is not a thing.

Even if you don't care about preact, we should probably fix this to reduce the amount of code going into front-end only builds.

adding script tag

I want to add script tag with "src" for loading external js files depend on the active component.
I tried:
const meta={ script:{src: "/path/to/example.js"} }
not working at all. Please, provide an example for this case and also an example for stylesheet link tag.

[WIP] v3 roadmap

  • Templating for title
  • Templating for descriptions (?)
  • List of meta tags with "same" keys/names
  • Split module into actual logic and SSR helpers
  • Force remove/update tags not initially controlled by react-document-meta

google sees the page without meta tags

at first glance, everything works well and in the code in the browser you can see meta tags. but when you view the page code there is nothing. and google sees the page without meta tags. I use the module on the product catalog page. all data is transferred. I can see everything in the reaction tools. but Google doesn't see it. after I start using this component, almost all pages are removed from the Google cache. I have
"react": "^16.2.0", "react-dom": "^16.2.0", "react-router": "^4.2.0", "react-router-dom": "^4.2.2",
"_id": "[email protected]"

Suppress `data-rdm` attributes?

Is there an option to suppress the data-rdm attributes added to each tag?

What is the purpose of these attributes?

(Thanks!)

the meta has already added. But the SNS website don't use the new meta

client-side rendering, the head html is:

<meta property="og:image" content="/favicon.png">
<meta name="description" content="Spiral, a professional grade crypto currencies exchange for quantitative trading, makes you a smarter trader.The most favored referral program, high performance, high liquidity, high security standard, support for sub-account management.">
<meta name="twitter:title" content="Spiral Cryptocurrency Exchange">
<meta name="twitter:description" content="Spiral, a professional grade crypto currencies exchange for quantitative trading, makes you a smarter trader.The most favored referral program, high performance, high liquidity, high security standard, support for sub-account management.">
<meta name="twitter:image" content="/favicon.png">
<meta property="twitter:title" content="穩定幣調研報告:USDT將何去何從?" data-rdm="">
<meta property="twitter:image" content="/research.jpg" data-rdm="">
<meta property="og:image" content="/research.jpg" data-rdm="">

But the SNS website don not use the new meta tags,it seems that it do not work.
Did i do something wrong? How dose it work

Describe idea behind children prop

Hello,

In readme and in examples I see that you suggest to put content as children of this component. I wonder what idea is behind this kind of approach instead use it as childless tag? Explanation in readme will be great. I can create PR with it if I get the purpose.

By the way I want to ask if code in render method can not be just replaced with return {this.props.children} for sake of simplicity and back compatibility?

Uncaught ReferenceError: require is not defined

I'm using react-document-meta@^1.0.0 and this is my package.json


"main": "src/server/index.js",
  "scripts": {
    "test": "jest",
    "start": "node src/server/index.js",
    "postinstall": "webpack --config config/webpack.js",
    "webpack": "webpack --config config/webpack.js",
    "webpack-watch": "webpack --config config/webpack.js --watch --colors"
  },
  "author": "RisingStack, Peter Marton",
  "license": "MIT",
  "homepage": "https://github.com/RisingStack/react-way-getting-started",
  "dependencies": {
    "debug": "^2.1.3",
    "express": "^4.12.3",
    "react": "^0.13.1",
    "react-document-meta": "^1.1.0",
    "react-native-fbsdk": "^0.1.0",
    "react-router": "~2.0.1",
    "react-social": "^1.0.7"
  },
  "devDependencies": {
    "babel": "^5.0.12",
    "babel-core": "^5.0.12",
    "babel-loader": "^5.0.0",
    "jest-cli": "^0.4.0",
    "webpack": "^1.8.4"
  },
  "jest": {
    "scriptPreprocessor": "./tools/preprocessor.js",
    "unmockedModulePathPatterns": [
      "react"
    ],
    "testPathDirs": [
      "./src/app",
      "./src/client"
    ]
  },
  "browserify": {
    "transform": [
      [
        "reactify"
      ]
    ]
  }
}

I followed the instruction but I keep getting:

bookprofile.js:1 Uncaught ReferenceError: require is not defined

when I render the page. with this in my file bookprofile.js

import React from 'react';
import DocumentMeta from 'react-document-meta';

Any idea on what might cause this?

'clone' bug: not all props can be serialized

The library claims to support the following useful pattern (see document-title):

<DocumentMeta>
  <Component />
</DocumentMeta>

Otherwise you're required to add a wrapping element and handle any styles it might need to help with layout, which is something I'd like to keep out of containers or routes.

<View>
  <DocumentMeta />
  <Component />
</View>

While there is some untested code in place to support this, we (Twitter) encountered a bug that arises from the JSON parse/stringify (your clone util) of props that contain unserializable data, e.g., Symbols or functions. I believe the current approach to cloning should collect only the props you're interested in.

es6 problem ?

I'm writing plain es5
Here's what I get with your example :
Image of Yaktocat
Is that the reason ? If it is, still possible to use it with es5 ?

DocumentMeta renders previous request data

Hi!

I'm using React + Redux + server side rendering and react-document-data to display og tags. When opening two different pages, the second one seems to be rendered with the first page tags.

I declare docMeta as seen in this example.

The problem is seen in this gif:

share

Initially, both pages are rendered with correct meta tags. When I reload "something" and go to "save-the-whales" tab and reload it, meta tags from "something" are displayed.

Is there something I'm missing on setting up react-document-meta?

[Question] Usage on create-react-app

Does this work in create-react-app without server-side rendering? I dont see changes happened in page source when using this. Can you help me to better understand this?

add a way to disable/remove an already defined tag

Instead of setting a value to an empty string, we should pass null, and remove/ignore that particular tag.

<div>
  <DocumentMeta meta={{ description: 'Some description' }} />
  <div>
    <DocumentMeta meta={{ description: null }} extend />
  </div>
</div>

Update react-side-effect to the latest version 2.1.1, please

Could you please update react-side-effect to its latest version, 2.1.1?

react-side-effect that react-document-meta is using still uses componentDidMount which will cause annoying warning message.

I saw latest react-side-effect has change it to unsafe_componentDidMount.

provide some real life examples

While updating readme , could you please show how can client side implementation be used in real world? with og tags is there anyway to test them to see its working?

Thanks.

Meta tags not changing

I plugging in my data into the metaData:

    let metaData = {
      title: aTutorial.headline,
      description: aTutorial.description,
      canonical: `https://www.stanleycyang.com${this.props.location.pathname}`,
      meta: {
        charset: 'utf-8',
        name: {
          keywords: keywordStr
        }
      }
    }

...

  return (
    <main>
        <DocumentMeta {...metaData} />
       ...
    </main>
  )

It doesn't change my meta data (description, keywords, etc). Not sure what I'm doing wrong.

1.0 upgrade trouble: clone fail

When upgrading to 1.0, I've got a problem where DocumentMetaWithSideEffect.peek() is returning undefined here, and JSON.parse() is falling over here.

All I have to do is change

{DocumentMeta.rewind({asReact: true})}

to

{DocumentMeta.renderAsReact()}

Right?

Title is getting set as an empty string

I'm using this library to add some tags to a page and I noticed that my page title was being set to an empty string, even though I was using the extend prop.

I got around this by setting the title again when rendering the <DocumentMeta /> component with this meta object:

const meta = {
    title: document.title,
    link: {
        ...
    }
}

I was looking at the source code and saw this line. Is there a reason why it sets the title to an empty string?

Facebook crawler

Hi

After several hours of testing and experimenting, I had found out that Facebook crawler is missing open graph meta tags generated by react-document-meta.

The following meta tags were created by react-document-meta in the head but were never read by Facebook crawler
image

until I had to hardcode the OG meta tags like the following:

image

The only difference I see between the two meta tags is the 'rdm' data attribute

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.