Skip to main content
Light Dark System

Copy Button

<sl-copy-button> | SlCopyButton
Since 2.7 experimental

Copies text data to the clipboard when the user clicks the trigger.

<sl-copy-button value="Shoelace rocks!"></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const App = () => (
  <SlCopyButton value="Shoelace rocks!" />
);

Examples

Custom Labels

Copy Buttons display feedback labels in a tooltip. You can change the labels by setting the copy-label, success-label, and error-label attributes.

<sl-copy-button
  value="Custom labels are easy"
  copy-label="Click to copy"
  success-label="You did it!"
  error-label="Whoops, your browser doesn't support this!"
></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const App = () => (
  <SlCopyButton
    value="Custom labels are easy"
    copy-label="Click to copy"
    success-label="You did it!"
    error-label="Whoops, your browser doesn't support this!"
  />
);

Custom Icons

Use the copy-icon, success-icon, and error-icon slots to customize the icons that get displayed for each state. You can use <sl-icon> or your own images.

<sl-copy-button value="Copied from a custom button">
  <sl-icon slot="copy-icon" name="clipboard"></sl-icon>
  <sl-icon slot="success-icon" name="clipboard-check"></sl-icon>
  <sl-icon slot="error-icon" name="clipboard-x"></sl-icon>
</sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
import { SlIcon } from '@shoelace-style/shoelace/dist/react/sl-icon';

const App = () => (
  <>
    <SlCopyButton value="Copied from a custom button">
      <SlIcon slot="copy-icon" name="clipboard" />
      <SlIcon slot="success-icon" name="clipboard-check" />
      <SlIcon slot="error-icon" name="clipboard-x" />
    </SlCopyButton>
  </>
);

Copying Values From Other Elements

Normally, the data that gets copied will come from the component’s value attribute, but you can copy data from any element within the same document by providing its id to the from attribute.

When using the from attribute, the element’s textContent will be copied by default. Passing an attribute or property modifier will let you copy data from one of the element’s attributes or properties instead.

To copy data from an attribute, use from="id[attr]" where id is the id of the target element and attr is the name of the attribute you’d like to copy. To copy data from a property, use from="id.prop" where id is the id of the target element and prop is the name of the property you’d like to copy.

+1 (234) 456–7890



Shoelace Website
<!-- Copies the span's textContent -->
<span id="my-phone">+1 (234) 456-7890</span>
<sl-copy-button from="my-phone"></sl-copy-button>

<br><br>

<!-- Copies the input's "value" property -->
<sl-input id="my-input" type="text" value="User input" style="display: inline-block; max-width: 300px;"></sl-input>
<sl-copy-button from="my-input.value"></sl-copy-button>

<br><br>

<!-- Copies the link's "href" attribute -->
<a id="my-link" href="https://shoelace.style/">Shoelace Website</a>
<sl-copy-button from="my-link[href]"></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
import { SlInput } from '@shoelace-style/shoelace/dist/react/sl-input';

const App = () => (
  <>
    {/* Copies the span's textContent */}
    <span id="my-phone">+1 (234) 456-7890</span>
    <SlCopyButton from="my-phone" />

    <br /><br />

    {/* Copies the input's "value" property */}
    <SlInput id="my-input" type="text" />
    <SlCopyButton from="my-input.value" />

    <br /><br />

    {/* Copies the link's "href" attribute */}
    <a id="my-link" href="https://shoelace.style/">Shoelace Website</a>
    <SlCopyButton from="my-link[href]" />
  </>
);

Handling Errors

Copy errors occur if the value is an empty string, if the from attribute points to an id that doesn’t exist, or if the browser rejects the operation for any reason. This example shows what happens when a copy error occurs.

<sl-copy-button from="i-do-not-exist"></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const App = () => (
  <SlCopyButton from="i-do-not-exist" />
);

Disabled

Copy buttons can be disabled by adding the disabled attribute.

<sl-copy-button value="You can't copy me" disabled></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const App = () => (
  <SlCopyButton value="You can't copy me" disabled />
);

Changing Feedback Duration

A success indicator is briefly shown after copying. You can customize the length of time the indicator is shown using the feedback-duration attribute.

<sl-copy-button value="Shoelace rocks!" feedback-duration="250"></sl-copy-button>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const App = () => (
  <SlCopyButton value="Shoelace rocks!" feedback-duration={250} />
);

Custom Styles

You can customize the button to your liking with CSS.

<sl-copy-button value="I'm so stylish" class="custom-styles"></sl-copy-button>

<style>
  .custom-styles {
    --success-color: white;
    --error-color: white;
    color: white;
  }

  .custom-styles::part(button) {
    background-color: #ff1493;
    border: solid 4px #ff7ac1;
    border-right-color: #ad005c;
    border-bottom-color: #ad005c;
    border-radius: 0;
    transition: 100ms scale ease-in-out, 100ms translate ease-in-out;
  }

  .custom-styles::part(button):hover {
    scale: 1.1;
  }

  .custom-styles::part(button):active {
    translate: 0 2px;
  }

  .custom-styles::part(button):focus-visible {
    outline: dashed 2px deeppink;
    outline-offset: 4px;
  }
</style>
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';

const css = `
  .custom-styles {
    --success-color: white;
    --error-color: white;
    color: white;
  }

  .custom-styles::part(button) {
    background-color: #ff1493;
    border: solid 4px #ff7ac1;
    border-right-color: #ad005c;
    border-bottom-color: #ad005c;
    border-radius: 0;
    transition: 100ms scale ease-in-out, 100ms translate ease-in-out;
  }

  .custom-styles::part(button):hover {
    scale: 1.1;
  }

  .custom-styles::part(button):active {
    translate: 0 2px;
  }

  .custom-styles::part(button):focus-visible {
    outline: dashed 2px deeppink;
    outline-offset: 4px;
  }
`;

const App = () => (
  <>
    <SlCopyButton value="I'm so stylish" className="custom-styles" />

    <style>{css}</style>
  </>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.6.0/cdn/components/copy-button/copy-button.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.6.0/cdn/components/copy-button/copy-button.js';

To import this component using a bundler:

import '@shoelace-style/shoelace/dist/components/copy-button/copy-button.js';

To import this component as a React component:

import SlCopyButton from '@shoelace-style/shoelace/dist/react/copy-button';

Slots

Name Description
copy-icon The icon to show in the default copy state. Works best with <sl-icon>.
success-icon The icon to show when the content is copied. Works best with <sl-icon>.
error-icon The icon to show when a copy error occurs. Works best with <sl-icon>.

Learn more about using slots.

Properties

Name Description Reflects Type Default
value The text value to copy. string ''
from An id that references an element in the same document from which data will be copied. If both this and value are present, this value will take precedence. By default, the target element’s textContent will be copied. To copy an attribute, append the attribute name wrapped in square brackets, e.g. from="el[value]". To copy a property, append a dot and the property name, e.g. from="el.value". string ''
disabled Disables the copy button. boolean false
copyLabel
copy-label
A custom label to show in the tooltip. string ''
successLabel
success-label
A custom label to show in the tooltip after copying. string ''
errorLabel
error-label
A custom label to show in the tooltip when a copy error occurs. string ''
feedbackDuration
feedback-duration
The length of time to show feedback before restoring the default trigger. number 1000
tooltipPlacement
tooltip-placement
The preferred placement of the tooltip. 'top' | 'right' | 'bottom' | 'left' 'top'
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
sl-copy onSlCopy Emitted when the data has been copied. -
sl-error onSlError Emitted when the data could not be copied. -

Learn more about events.

Custom Properties

Name Description Default
--success-color The color to use for success feedback.
--error-color The color to use for error feedback.

Learn more about customizing CSS custom properties.

Parts

Name Description
button The internal <button> element.

Learn more about customizing CSS parts.

Animations

Name Description
copy.in The animation to use when feedback icons animate in.
copy.out The animation to use when feedback icons animate out.

Learn more about customizing animations.

Dependencies

This component automatically imports the following dependencies.

  • <sl-icon>
  • <sl-popup>
  • <sl-tooltip>