Coder Perfect

How do I copy text to the clipboard in reactJS?

Problem

I’m using ReactJS and I’d like to copy some text to the clipboard when a user clicks a link.

I’m using Chrome 52 and don’t have any other browsers to support.

I don’t understand why this code doesn’t copy the info to the clipboard. (The code sample was taken from a Reddit post).

Is it possible that I’m doing something incorrectly? Is there a “proper” approach to do copy to clipboard with reactjs, as far as anyone can tell?

copyToClipboard = (text) => {
  console.log('text', text)
  var textField = document.createElement('textarea')
  textField.innerText = text
  document.body.appendChild(textField)
  textField.select()
  document.execCommand('copy')
  textField.remove()
}

Asked by Duke Dougal

Solution #1

If you wish to programatically write data to the clipboard, use this simple inline onClick function on a button.

onClick={() => {navigator.clipboard.writeText(this.state.textToCopy)}}

Answered by Gary Vernon Grubb

Solution #2

Personally, I don’t believe a library is required for this. According to http://caniuse.com/#feat=clipboard, it’s quite generally supported now, but you can still check to see if the capability is available in the current client and just hide the copy button if it isn’t.

import React from 'react';

class CopyExample extends React.Component {

  constructor(props) {
    super(props);

    this.state = { copySuccess: '' }
  }

  copyToClipboard = (e) => {
    this.textArea.select();
    document.execCommand('copy');
    // This is just personal preference.
    // I prefer to not show the whole text area selected.
    e.target.focus();
    this.setState({ copySuccess: 'Copied!' });
  };

  render() {
    return (
      <div>
        {
         /* Logical shortcut for only displaying the 
            button if the copy command exists */
         document.queryCommandSupported('copy') &&
          <div>
            <button onClick={this.copyToClipboard}>Copy</button> 
            {this.state.copySuccess}
          </div>
        }
        <form>
          <textarea
            ref={(textarea) => this.textArea = textarea}
            value='Some text to copy'
          />
        </form>
      </div>
    );
  }

}

export default CopyExample;

React 16.7.0-alpha.0 has been updated with React Hooks.

import React, { useRef, useState } from 'react';

export default function CopyExample() {

  const [copySuccess, setCopySuccess] = useState('');
  const textAreaRef = useRef(null);

  function copyToClipboard(e) {
    textAreaRef.current.select();
    document.execCommand('copy');
    // This is just personal preference.
    // I prefer to not show the whole text area selected.
    e.target.focus();
    setCopySuccess('Copied!');
  };

  return (
    <div>
      {
       /* Logical shortcut for only displaying the 
          button if the copy command exists */
       document.queryCommandSupported('copy') &&
        <div>
          <button onClick={copyToClipboard}>Copy</button> 
          {copySuccess}
        </div>
      }
      <form>
        <textarea
          ref={textAreaRef}
          value='Some text to copy'
        />
      </form>
    </div>
  );
}

Answered by Nate

Solution #3

You can do this without using an external library, for example, within a button.

<button 
  onClick={() =>  navigator.clipboard.writeText('Copy this text to clipboard')}
>
  Copy
</button>

If you’re using Internet Explorer 11 or an earlier browser, you may need to tweak the code slightly. Here’s an example:

<button 
  onClick={() =>  window.clipboardData.setData("Text", 'Copy this text to clipboard')}>
 Copy
</button>

Hope this helps.

Answered by jerryurenaa

Solution #4

You should probably use a package like the one recommended by @Shubham, however I made a functioning codepen based on what you described: http://codepen.io/dtschust/pen/WGwdVN?editors=1111, http://codepen.io/dtschust/pen/WGwdVN?editors=1111, http://codepen.io It works in Chrome in my browser, so see if there’s something I done there that you missed, or if your application has some added complexity that precludes this from working.

// html
<html>
  <body>
    <div id="container">

    </div>
  </body>
</html>


// js
const Hello = React.createClass({
  copyToClipboard: () => {
    var textField = document.createElement('textarea')
    textField.innerText = 'foo bar baz'
    document.body.appendChild(textField)
    textField.select()
    document.execCommand('copy')
    textField.remove()
  },
  render: function () {
    return (
      <h1 onClick={this.copyToClipboard}>Click to copy some text</h1>
    )
  }
})

ReactDOM.render(
<Hello/>,
  document.getElementById('container'))

Answered by Drew Schuster

Solution #5

The react-copy-to-clipboard npm package is the simplest way.

The command to install it is as follows:

npm install --save react react-copy-to-clipboard

It can be used in the following ways.

const App = React.createClass({
  getInitialState() {
    return {value: '', copied: false};
  },


  onChange({target: {value}}) {
    this.setState({value, copied: false});
  },


  onCopy() {
    this.setState({copied: true});
  },


  render() {
    return (
      <div>

          <input value={this.state.value} size={10} onChange={this.onChange} />

        <CopyToClipboard text={this.state.value} onCopy={this.onCopy}>
          <button>Copy</button>
        </CopyToClipboard>

                <div>
        {this.state.copied ? <span >Copied.</span> : null}
                </div>
        <br />

        <input type="text" />

      </div>
    );
  }
});

ReactDOM.render(<App />, document.getElementById('container'));

The following link contains a full explanation.

https://www.npmjs.com/package/react-copy-to-clipboard

Here’s a fiddle that’s on the go.

Answered by Shubham Khatri

Post is based on https://stackoverflow.com/questions/39501289/in-reactjs-how-to-copy-text-to-clipboard