DEV Community

Cover image for Implement the useCopy custom hook in React
Debajit Mallick
Debajit Mallick

Posted on

Implement the useCopy custom hook in React

Introduction

Copying text to the clipboard is a common feature in web apps. If you're letting your users copy coupon codes, share links, or export values with a single click. Instead of writing this logic repeatedly, why not encapsulate it in a clean and reusable custom React hook?

In this blog, we'll build a useCopy hook from scratch, understand each part of the implementation, and see a real-world example to use it in your UI.

What Is the Clipboard API?

Modern browsers offer a Clipboard API under the navigator.clipboard object, which allows us to:

  • Programmatically read or write text
  • Interact with the system clipboard securely
  • Do it asynchronously

But since not all environments support it (especially older browsers or HTTP connections), we should handle fallbacks or at least warn the user.

useCopy Hook

import { useState } from 'react';

const useCopy = () => {
  const [copiedText, setCopiedText] = useState();

  const copy = async (text) => {
    if (!navigator?.clipboard) {
      console.warn('Clipboard not supported');
      return false;
    }

    try {
      await navigator.clipboard.writeText(text);
      setCopiedText(text);
    } catch (error) {
      console.error(`Failed to copy text ${text} `, error);
      setCopiedText(null);
    }
  };

  return { copiedText, copy };
};

export default useCopy;
Enter fullscreen mode Exit fullscreen mode

Now, let's understand the code step by step:

State Management

const [copiedText, setCopiedText] = useState();
Enter fullscreen mode Exit fullscreen mode

We store the latest copied text so the component can display feedback (like a tooltip or success message).

Clipboard API Check

if (!navigator?.clipboard) {
  console.warn('Clipboard not supported');
  return false;
}
Enter fullscreen mode Exit fullscreen mode
  • navigator is a global browser object that contains info about the browser and OS.
  • navigator.clipboard is where the Clipboard API lives.
  • We use optional chaining (?.) to safely check if it exists.

Writing to the Clipboard

await navigator.clipboard.writeText(text);
setCopiedText(text);
Enter fullscreen mode Exit fullscreen mode

This performs the actual copy-to-clipboard action. If it succeeds, we store the text. If it fails, we catch and log the error:

} catch (error) {
  console.error(`Failed to copy text ${text} `, error);
  setCopiedText(null);
}
Enter fullscreen mode Exit fullscreen mode

Example Usage

Here’s how you can use useCopy in a functional React component:

import React from 'react';
import useCopy from './useCopy';

const CopyExample = () => {
  const { copiedText, copy } = useCopy();
  const textToCopy = 'https://dev.to/debajit13/';

  return (
    <div>
      <p>Click below to copy the link:</p>
      <button onClick={() => copy(textToCopy)}>Copy Link</button>
      {copiedText === textToCopy && <span>Text Copied Successfully!</span>}
    </div>
  );
};

export default CopyExample;
Enter fullscreen mode Exit fullscreen mode

When you click the button, the link is copied to your clipboard. A success message is shown once copied.

Bonus: Deep dive into navigator

navigator is part of the Browser Object Model (BOM) in JavaScript. It provides useful properties and methods such as:

  • navigator.userAgent — info about the browser
  • navigator.onLine — check if the user is online
  • navigator.clipboard — read/write access to the system clipboard

Conclusion

The useCopy hook is a small but powerful utility that makes your app feel modern, interactive, and user-friendly. It abstracts away messy clipboard logic and gives you a clean, declarative interface for one of the most common UX features. If you liked this blog and want to learn more about Frontend Development and Software Engineering, you can follow me on Dev.

Top comments (0)