{"id":13469718,"url":"https://github.com/lgarron/clipboard-polyfill","last_synced_at":"2026-01-22T01:16:43.953Z","repository":{"id":29427078,"uuid":"32962894","full_name":"lgarron/clipboard-polyfill","owner":"lgarron","description":":clipboard: Simple copying on the web, with maximum browser compatibility. (You probably don't need this anymore!)","archived":false,"fork":false,"pushed_at":"2025-11-06T21:26:26.000Z","size":962,"stargazers_count":926,"open_issues_count":9,"forks_count":100,"subscribers_count":8,"default_branch":"main","last_synced_at":"2026-01-14T08:41:14.710Z","etag":null,"topics":["api","clipboard","copy","javascript","paste","polyfill","ponyfill","web"],"latest_commit_sha":null,"homepage":"https://garron.net/code/clipboard-polyfill/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lgarron.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2015-03-27T02:10:34.000Z","updated_at":"2026-01-12T02:09:49.000Z","dependencies_parsed_at":"2024-01-14T15:24:29.836Z","dependency_job_id":"aee13a7f-2553-4f0d-9085-7716639d63c1","html_url":"https://github.com/lgarron/clipboard-polyfill","commit_stats":{"total_commits":491,"total_committers":16,"mean_commits":30.6875,"dds":"0.050916496945010215","last_synced_commit":"c24845e280262858cf40c5fce8443abf5a8dc51b"},"previous_names":["lgarron/clipboard.js"],"tags_count":69,"template":false,"template_full_name":null,"purl":"pkg:github/lgarron/clipboard-polyfill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgarron%2Fclipboard-polyfill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgarron%2Fclipboard-polyfill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgarron%2Fclipboard-polyfill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgarron%2Fclipboard-polyfill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lgarron","download_url":"https://codeload.github.com/lgarron/clipboard-polyfill/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lgarron%2Fclipboard-polyfill/sbom","scorecard":{"id":586929,"data":{"date":"2025-08-11","repo":{"name":"github.com/lgarron/clipboard-polyfill","commit":"ce3cd2891302c40772b60e1b440d090252cd4b8c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/publish-github-release.yaml:11","Warn: no topLevel permission defined: .github/workflows/CI.yml:1","Warn: no topLevel permission defined: .github/workflows/publish-github-release.yaml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CI.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CI.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/CI.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish-github-release.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/lgarron/clipboard-polyfill/publish-github-release.yaml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 3 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T20:46:07.048Z","repository_id":29427078,"created_at":"2025-08-20T20:46:07.048Z","updated_at":"2025-08-20T20:46:07.048Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28416972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:18:03.274Z","status":"ssl_error","status_checked_at":"2026-01-14T10:16:11.865Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","clipboard","copy","javascript","paste","polyfill","ponyfill","web"],"created_at":"2024-07-31T15:01:52.451Z","updated_at":"2026-01-22T01:16:43.936Z","avatar_url":"https://github.com/lgarron.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Esbuild"],"sub_categories":["lgarron/clipboard-polyfill"],"readme":"![Logo for clipboard-polyfill: an icon of a clipboard fading into a drafting paper grid.](clipboard-polyfill-logo.svg)\n\n# `clipboard-polyfill`\n\n## ⚠️ You don't need `clipboard-polyfill` to copy text! ⚠️\n\nNote: As of 2020, you can use `navigator.clipboard.writeText(...)` [in the stable versions of all major browsers](https://caniuse.com/mdn-api_clipboard_writetext). This library will only be useful to you if you want to:\n\n- target very old browsers (see below for compatibility) for text copy,\n- copy `text/html` in Firefox ≤126,\n- use the `ClipboardItem` API in Firefox ≤126, or\n- polyfill the API shape in a non-browser environment (e.g. in [`jsdom`](https://github.com/jsdom/jsdom/issues/1568)).\n\nSee the [Compatibility section](#compatibility) below for more details.\n\n---\n\n## Summary\n\nMakes copying on the web as easy as:\n\n```js\nclipboard.writeText(\"hello world\");\n```\n\nThis library is a [ponyfill](https://github.com/sindresorhus/ponyfill)/polyfill for the modern `Promise`-based [asynchronous clipboard API](https://www.w3.org/TR/clipboard-apis/#async-clipboard-api).\n\n## Usage\n\nIf you use `npm`, install:\n\n```shell\nnpm install clipboard-polyfill\n```\n\nSample app that copies text to the clipboard:\n\n```js\nimport * as clipboard from \"clipboard-polyfill\";\n\nfunction handler() {\n  clipboard.writeText(\"This text is plain.\").then(\n    () =\u003e { console.log(\"success!\"); },\n    () =\u003e { console.log(\"error!\"); }\n  );\n}\n\nwindow.addEventListener(\"DOMContentLoaded\", function () {\n  const button = document.body.appendChild(document.createElement(\"button\"));\n  button.textContent = \"Copy\";\n  button.addEventListener(\"click\", handler);\n});\n```\n\nNotes:\n\n- You need to call a clipboard operation in response to a user gesture (e.g. the event handler for a `button` click).\n  - Some browsers may only allow one clipboard operation per gesture.\n\n## `async`/`await` syntax\n\n```js\nimport * as clipboard from \"clipboard-polyfill\";\n\nasync function handler() {\n  console.log(\"Previous clipboard text:\", await clipboard.readText());\n\n  await clipboard.writeText(\"This text is plain.\");\n}\n\nwindow.addEventListener(\"DOMContentLoaded\", function () {\n  const button = document.body.appendChild(document.createElement(\"button\"));\n  button.textContent = \"Copy\";\n  button.addEventListener(\"click\", handler);\n});\n```\n\n## More MIME types (data types)\n\n```js\nimport * as clipboard from \"clipboard-polyfill\";\n\nasync function handler() {\n  console.log(\"Previous clipboard contents:\", await clipboard.read());\n\n  const item = new clipboard.ClipboardItem({\n    \"text/html\": new Blob(\n      [\"\u003ci\u003eMarkup\u003c/i\u003e \u003cb\u003etext\u003c/b\u003e. Paste me into a rich text editor.\"],\n      { type: \"text/html\" }\n    ),\n    \"text/plain\": new Blob(\n      [\"Fallback markup text. Paste me into a rich text editor.\"],\n      { type: \"text/plain\" }\n    ),\n  });\n  await clipboard.write([item]);\n}\n\nwindow.addEventListener(\"DOMContentLoaded\", function () {\n  const button = document.body.appendChild(document.createElement(\"button\"));\n  button.textContent = \"Copy\";\n  button.addEventListener(\"click\", handler);\n});\n```\n\nCheck [the Clipboard API specification](https://www.w3.org/TR/clipboard-apis/#clipboard-interface) for more details.\n\nNotes:\n\n- You'll need to use `async` functions for the `await` syntax.\n- Currently, `text/plain` and `text/html` are the only data types that can be written to the clipboard across most browsers.\n- If you try to copy unsupported data types, they may be silently dropped (e.g. Safari 13.1) or the call may throw an error (e.g. Chrome 83). In general, it is not possible to tell when data types are dropped.\n- In some current browsers, `read()` may only return a subset of supported data types, even if the clipboard contains more data types. There is no way to tell if there were more data types.\n\n### `overwrite-globals` version\n\nIf you want the library to overwrite the global clipboard API with its implementations, import `clipboard-polyfill/overwrite-globals`. This will turn the library from a [ponyfill](https://ponyfill.com/) into a proper polyfill, so you can write code as if the async clipboard API were already implemented in your browser:\n\n```js\nimport \"clipboard-polyfill/overwrite-globals\";\n\nasync function handler() {\n  const item = new window.ClipboardItem({\n    \"text/html\": new Blob(\n      [\"\u003ci\u003eMarkup\u003c/i\u003e \u003cb\u003etext\u003c/b\u003e. Paste me into a rich text editor.\"],\n      { type: \"text/html\" }\n    ),\n    \"text/plain\": new Blob(\n      [\"Fallback markup text. Paste me into a rich text editor.\"],\n      { type: \"text/plain\" }\n    ),\n  });\n\n  navigator.clipboard.write([item]);\n}\n\nwindow.addEventListener(\"DOMContentLoaded\", function () {\n  const button = document.body.appendChild(document.createElement(\"button\"));\n  button.textContent = \"Copy\";\n  button.addEventListener(\"click\", handler);\n});\n```\n\nThis approach is not recommended, because it may break any other code that interacts with the clipboard API globals, and may be incompatible with future browser implementations.\n\n### Flat-file version with `Promise` included\n\nIf you need to grab a version that \"just works\", download [`clipboard-polyfill.window-var.promise.es5.js`](https://unpkg.com/clipboard-polyfill/dist/es5/window-var/clipboard-polyfill.window-var.promise.es5.js) and include it using a `\u003cscript\u003e` tag:\n\n```html\n\u003cscript src=\"./clipboard-polyfill.window-var.promise.es5.js\"\u003e\u003c/script\u003e\n\u003cbutton onclick=\"copy()\"\u003eCopy text!\u003c/button\u003e\n\u003cscript\u003e\n  // `clipboard` is defined on the global `window` object.\n  function copy() {\n    clipboard.writeText(\"hello world!\");\n  }\n\u003c/script\u003e\n```\n\n### Bundling / tree shaking / minification / CommonJS\n\nThanks to the conveniences of the modern JS ecosystem, we do not provide tree shaken, minified, or CommonJS builds anymore. To get such builds without losing compatibility, pass `clipboard-polyfill` builds through `esbuild`. For example:\n\n```shell\nmkdir temp \u0026\u0026 cd temp \u0026\u0026 npm install clipboard-polyfill esbuild\n\n# Minify the ES6 build:\necho 'export * from \"clipboard-polyfill\";' | npx esbuild --format=esm --target=es6 --bundle --minify\n\n# Include just the `writeText(…)` export and minify:\necho 'export { writeText } from \"clipboard-polyfill\";' | npx esbuild --format=esm --target=es6 --bundle --minify\n\n# Minify an ES5 build:\nnpx esbuild --format=esm --target=es5 --bundle --minify node_modules/clipboard-polyfill/dist/es5/window-var/clipboard-polyfill.window-var.promise.es5.js\n\n# Get a CommonJS build:\necho 'export * from \"clipboard-polyfill\";' | npx esbuild --format=cjs --target=es6 --bundle\n```\n\n## Why `clipboard-polyfill`?\n\nBrowsers have implemented several clipboard APIs over time, and writing to the clipboard without [triggering bugs in various old and current browsers](https://github.com/lgarron/clipboard-polyfill/blob/master/experiment/Conclusions.md) is fairly tricky. In every browser that supports copying to the clipboard in some way, `clipboard-polyfill` attempts to act as close as possible to the async clipboard API. (See above for disclaimers and limitations.)\n\nSee [this presentation](https://docs.google.com/presentation/d/1Ix2rYi67hbZoIQsd85kspkUPLi8Q-PZopy_AtfafHW0) for for a longer history of clipboard access on the web.\n\n## Compatibility\n\n- ☑️: Browser has native async clipboard support.\n- ✅: `clipboard-polyfill` adds support.\n- ❌: Support is not possible.\n- **Bold browser names** indicate the latest functionality changes for stable versions of modern browsers.\n\nWrite support by earliest browser version:\n\n| Browser                                     | `writeText()` | `write()` (HTML) | `write()` (other formats)          |\n| ------------------------------------------- | ------------- | ---------------- | ---------------------------------- |\n| **Safari 13.1**                             | ☑️            | ☑️               | ☑️ (`image/uri-list`, `image/png`) |\n| **Chrome 86**ᵃ / **Edge 86**                | ☑️            | ☑️               | ☑️ (`image/png`)                   |\n| Chrome 76ᵃ / Edge 79                        | ☑️            | ✅               | ☑️ (`image/png`)                   |\n| Chrome 66ᵃ / **Firefox 63**                 | ☑️            | ✅               | ❌                                 |\n| Safari 10 / Chrome 42ᵃ / Edgeᵈ / Firefox 41 | ✅            | ✅ᵇ              | ❌                                 |\n| IE 9                                        | ✅ᶜ           | ❌               | ❌                                 |\n\nRead support:\n\n| Browser                                                                             | `readText()` | `read()` (HTML) | `read()` (other formats)           |\n| ----------------------------------------------------------------------------------- | ------------ | --------------- | ---------------------------------- |\n| **Safari 13.1**                                                                     | ☑️           | ☑️              | ☑️ (`image/uri-list`, `image/png`) |\n| **Chrome [76](https://web.dev/image-support-for-async-clipboard/)** ᵃ / **Edge 79** | ☑️           | ❌              | ☑️ (`image/png`)                   |\n| Chrome [66](https://developers.google.com/web/updates/2018/03/clipboardapi)ᵃ        | ☑️           | ❌              | ❌                                 |\n| IE 9                                                                                | ✅ᶜ          | ❌              | ❌                                 |\n| **Firefox**                                                                         | ❌           | ❌              | ❌                                 |\n\n- ᵃ Also includes versions of Edge, Opera, Brave, Vivaldi, etc. based on the corresponding version of Chrome.\n- ᵇ HTML did not work properly on mobile Safari in the first few releases of version 10.\n- ᶜ In Internet Explorer, you will need to polyfill `window.Promise` if you want the library to work.\n- ᵈ In older versions of Edge (Spartan):\n  - It may not be possible to tell if a copy operation succeeded ([Edge Bug #14110451](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14110451/), [Edge Bug #14080262](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14080262/)). `clipboard-polyfill` will always report success in this case.\n  - Only the _last_ data type you specify is copied to the clipboard ([Edge Bug #14080506](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14080506/)). Consider placing the most important data type last in the object that you pass to the `ClipboardItem` constructor.\n  - The `text/html` data type is not written using the expected `CF_HTML` format. `clipboard-polyfill` does _not_ try to work around this, since 1) it would require fragile browser version sniffing, 2) users of Edge are not generally stuck on version \u003c 17, and 3) the failure mode for other browsers would be that invalid clipboard HTML is copied. ([Edge Bug #14372529](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14372529/), [#73](https://github.com/lgarron/clipboard-polyfill/issues/73))\n\n`clipboard-polyfill` uses a variety of heuristics to work around compatibility bugs. Please [let us know](https://github.com/lgarron/clipboard-polyfill/issues/new) if you are running into compatibility issues with any of the browsers listed above.\n\n## History\n\n### Browser history\n\n| Browser | First version supporting\u003cbr\u003e`navigator.clipboard.writeText(...)` | Release Date |\n| ------- | ------------------------------------------------------------- | ------------ |\n| Chrome  | 66+                                                           | April 2018   |\n| Firefox | 53+                                                           | October 2018 |\n| Edge    | 79+ (first Chromium-based release)                            | January 2020 |\n| Safari  | 13.1+                                                         | March 2020   |\n\n### Project history\n\nThis project dates from a time when clipboard access in JS was barely becoming possible, and [ergonomic clipboard API efforts were stalling](https://lists.w3.org/Archives/Public/public-webapps/2015JulSep/0235.html). (See [this presentation](https://docs.google.com/presentation/d/1Ix2rYi67hbZoIQsd85kspkUPLi8Q-PZopy_AtfafHW0/) for a bit more context.) Fortunately, [an ergonomic API with the same functionality](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) is now available in all modern browsers since 2020:\n\n- 2015: Browsers [start supporting](https://caniuse.com/mdn-api_document_execcommand_copy) the [defunct](https://w3c.github.io/editing/docs/execCommand/) `document.execCommand(\"copy\")` call (with [many, many issues](./experiment/Conclusions.md)).\n- 2015: Started this project as `clipboard.js` (half a year before @zenorocha picked [the same name](https://github.com/zenorocha/clipboard.js) 😛).\n- 2016: Renewed discussions about an async clipboard API (e.g. [proposal doc](https://docs.google.com/document/d/1QI5rKJSiYeD9ekP2NyCYJuOnivduC9-tqEOn-GsCGS4/edit#), [`crbug.com/593475`](https://bugs.chromium.org/p/chromium/issues/detail?id=593475)).\n- 2017: Renamed this project to `clipboard-polyfill` to reflect a `v2` API overhaul aligned with the draft spec.\n- 2018: Browsers [start supporting](https://caniuse.com/mdn-api_clipboard_writetext) `navigator.clipboard.writeText()`.\n- 2020: Browsers [start supporting](https://caniuse.com/mdn-api_clipboard_write) `navigator.clipboard.write()` (including `text/html` support).\n\nThanks to Gary Kacmarcik, Hallvord Steen, and others for helping to bring the [async clipboard API](https://w3c.github.io/clipboard-apis/) to life!\n\n## This is way too complicated!\n\nIf you only need to copy text in modern browsers, consider using `navigator.clipboard.writeText()` directly: \u003chttps://caniuse.com/mdn-api_clipboard_writetext\u003e\n\nIf you need copy text in older browsers as well, you could also try [this gist](https://gist.github.com/lgarron/d1dee380f4ed9d825ca7) for a simple hacky solution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgarron%2Fclipboard-polyfill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flgarron%2Fclipboard-polyfill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgarron%2Fclipboard-polyfill/lists"}