### Blacklist Configuration Example
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/smart-rules-for-blacklist.md
Demonstrates how to configure blacklist rules using hostnames, @exclude-match, and @exclude patterns. Comments are ignored.
```plaintext
# hostnames
www.google.com
# @exclude-match rules
*://twitter.com/*
# @exclude rules
@exclude https://example.com/*
```
--------------------------------
### Install and Import @violentmonkey/shortcut
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Install the library using NPM and import its functions directly into your code. This method is recommended for projects using bundlers and TypeScript.
```bash
$ npm i @violentmonkey/shortcut
```
```js
import { register } from '@violentmonkey/shortcut';
```
--------------------------------
### Start Development Server
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md
Run the development command to watch for source code changes and automatically recompile them to the dist directory.
```bash
$ npm run dev
```
--------------------------------
### Whitelist Configuration Example
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/smart-rules-for-blacklist.md
Shows how to set up a whitelist using @match and @include rules, followed by a catch-all '*' rule to block all other URLs.
```plaintext
# match rules
@match https://www.google.com/*
# include rules
@include https://example.com/*
# block everything else
*
```
--------------------------------
### GM.xmlHttpRequest Example
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
This example shows how to use GM.xmlHttpRequest, which is compatible with multiple userscript managers. It demonstrates a basic request with an onload handler.
```javascript
// compatible with multiple userscript managers
GM.xmlHttpRequest({ url, onload: res => {/*....*/} });
```
--------------------------------
### Basic @match and @exclude-match Rules
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md
These are examples of basic @match and @exclude-match rules. @match defines URLs where the script should run, while @exclude-match defines URLs to be excluded.
```javascript
// @match *://*/*
// @exclude-match *://*.tk/*
```
--------------------------------
### Basic @include and @exclude Rules
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md
Examples of @include and @exclude rules. @include specifies URLs to run the script on, and @exclude specifies URLs to prevent the script from running. These can be simple strings or regular expressions.
```javascript
// @include *
// @include https://www.google.com/*
// @include /\.com\.hk\/
// @exclude https://www.google.com/exact/url
```
--------------------------------
### GM.xmlHttpRequest with Abort Control (VM2.18.3+, TM)
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
This example demonstrates how to get a control object from GM.xmlHttpRequest to abort the request, using async/await syntax. Available in Violent Monkey version 2.18.3 and later, and Tampermonkey.
```javascript
// VM2.18.3+, TM
const control = GM.xmlHttpRequest({ url });
myButton.addEventListener('click', control.abort, { once: true });
const res = await control;
```
--------------------------------
### GM.xmlHttpRequest with Promise Wrapper
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
This example demonstrates wrapping GM.xmlHttpRequest in a Promise for easier asynchronous handling, compatible with multiple userscript managers.
```javascript
// compatible with multiple userscript managers
const res = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({ url, onload: resolve, onerror: reject });
});
```
--------------------------------
### Run Userscript on Entire SPA Site
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md
This example shows how to use the @match rule to ensure a userscript runs on an entire Single Page Application (SPA) site, like YouTube.
```javascript
// @match *://www.youtube.com/*
```
--------------------------------
### GM.xmlHttpRequest Async/Await (VM2.18.3+, TM)
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
This example shows the modern async/await usage for GM.xmlHttpRequest, available in Violent Monkey version 2.18.3 and later, and Tampermonkey.
```javascript
// VM2.18.3+, TM
const res = await GM.xmlHttpRequest({ url });
```
--------------------------------
### Get text resource from metadata
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves the content of a text resource defined in the script's metadata block.
```javascript
let text = GM_getResourceText(name)
```
--------------------------------
### Get a value from storage
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves a specific value from the script's storage. If the key does not exist, it returns the provided default value.
```javascript
let value = GM_getValue(key, defaultValue)
```
--------------------------------
### Userscript Metadata Block Structure
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The metadata block must start with `// ==UserScript==` and end with `// ==/UserScript==`. Each line within the block must begin with `//` followed by a single space.
```javascript
// ==UserScript==
// @key value
// ==/UserScript==
```
--------------------------------
### Get Resource URL
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves a blob: or data: URL for a resource defined in the metadata block. Use isBlobUrl=true for a cacheable blob: URL, or false for a data: URL which is useful for sites with strict CSP.
```javascript
let blobUrl = GM_getResourceURL(name);
let blobOrDataUrl = GM_getResourceURL(name, isBlobUrl);
```
--------------------------------
### Get multiple values from storage
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves multiple values from the script's storage. Can accept an array of keys or an object where keys are names and values are defaults.
```javascript
let values = GM_getValues(['foo', 'bar'])
```
```javascript
let values = GM_getValues({ foo: 1, bar: [2] })
```
--------------------------------
### Create Project Directory
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md
Create a new directory for your userscript project and navigate into it.
```bash
$ mkdir my-script
$ cd my-script
```
--------------------------------
### Initialize New Userscript Project
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md
Use npx to generate a new userscript project with a modern JavaScript toolchain, including Babel for compilation and Rollup for bundling.
```bash
$ npx -p github:violentmonkey/generator-userscript -p yo yo @violentmonkey/userscript
```
--------------------------------
### Build Userscript for Production
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md
Execute the build command to compile the source code once for production deployment. This process syncs version and author information from package.json.
```bash
$ npm run build
```
--------------------------------
### Register a Key Sequence Shortcut
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Bind a sequence of key combinations (e.g., 'c-a c-b' for Ctrl+A followed by Ctrl+B) to a callback function.
```js
VM.shortcut.register('c-a c-b', () => {
console.log('You just pressed Ctrl-A Ctrl-B sequence');
});
```
--------------------------------
### Demonstration of Synchronous vs. Asynchronous Injection
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md
This code demonstrates the difference in execution order between synchronous textContent injection and asynchronous Blob URL injection. The synchronous method logs '1' then '3' then '2', while the asynchronous method logs '1', '3', and finally '2'.
```javascript
{
const s = document.createElement('script');
s.textContent = 'console.log(1)';
document.body.appendChild(s);
document.body.removeChild(s);
}
{
const s = document.createElement('script');
const b = new Blob(['console.log(2)'], { type: 'text/javascript' });
const u = URL.createObjectURL(b);
s.src = u;
document.body.appendChild(s);
document.body.removeChild(s);
URL.revokeObjectURL(u);
}
console.log(3);
```
--------------------------------
### GM_openInTab
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Opens a URL in a new tab, with options to control its behavior like activation, pinning, and container.
```APIDOC
## GM_openInTab
Opens URL in a new tab.
### Usage
1. Using an object for options:
```js
let tabControl = GM_openInTab(url, options)
```
- **url** (string) - Required - The URL to open in a new tab. Relative URLs are also allowed.
Note that `data:`, `blob:`, `chrome:`, `file:`, and many `about:` URLs are disallowed for security reasons.
- **options** (object) - Optional
- **active** (boolean) - Optional, defaultValue: `true` - Make the new tab active (open in foreground).
- **container** (number) - Optional, since VM2.12.5, Firefox-only - Set tab's container in Firefox:
* not specified = reuse script's tab container
* `0` = default (main) container
* `1`, `2`, etc. = internal container index
- **insert** (boolean) - Optional, since VM2.11.0, defaultValue: `true` - Insert the new tab next to the current tab and set its "openerTab" so when it's closed the original tab will be focused automatically. When `false` or not specified, the usual browser behavior is to open the tab at the end of the tab list.
- **pinned** (boolean) - Optional, since VM2.12.5, defaultValue: `false` - Pin the tab (show without a title at the beginning of the tab list).
2. Using a boolean for background opening (compatible with Greasemonkey):
```js
let tabControl = GM_openInTab(url, openInBackground)
```
- **openInBackground** (boolean) - Required - Open the tab in background. `true` is the same as `{ active: false }`.
### Returns
An object with the following properties:
- **onclose** (function) - Optional - Can be assigned to a function. If provided, it will be called when the opened tab is closed.
- **closed** (boolean) - Whether the opened tab is closed.
- **close** (function) - A function to explicitly close the opened tab.
### Example
```js
let tabControl = GM_openInTab(url);
tab.onclose = () => console.log('tab is closed');
tab.close();
```
```
--------------------------------
### GM_download with options object
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Downloads a URL to a local file using an options object. Supports various configuration options for the download process.
```APIDOC
## GM_download(options)
### Description
Downloads a URL to a local file using an options object. Most [GM_xmlhttpRequest](#gm_xmlhttprequest) options are supported.
### Parameters
#### Request Body
- **options** (object) - Required - An object containing download configuration.
- **url** (string) - Required - The URL to download.
- **name** (string) - Required - The filename to save to. Folders/subpaths aren't supported yet.
- **headers?** (object) - Optional - Custom headers for the request.
- **timeout?** (number) - Optional (since VM2.9.5) - Timeout for the download in milliseconds.
- **context?** (any) - Optional (since VM2.13.4) - Context for the request.
- **user?** (string) - Optional (since VM2.13.4) - Username for authentication.
- **password?** (string) - Optional (since VM2.13.4) - Password for authentication.
- **anonymous?** (boolean) - Optional (since VM2.13.4, default: false) - Whether to use anonymous download.
- **onabort?** (function) - Optional (since VM2.13.4) - Callback for when the download is aborted.
- **onerror?** (function) - Optional - Callback for when an error occurs during download.
- **onload?** (function) - Optional - Callback for when the download is successful. Called after data is downloaded, before writing the file.
- **onloadend?** (function) - Optional (since VM2.13.4) - Callback for when the download finishes (success or error).
- **onloadstart?** (function) - Optional (since VM2.13.4) - Callback for when the download starts.
- **onprogress?** (function) - Optional - Callback for download progress.
- **onreadystatechange?** (function) - Optional (since VM2.13.4) - Callback for changes in the ready state.
- **ontimeout?** (function) - Optional - Callback for when the download times out.
### Returns
- **object** - A control object with an `abort` function to cancel the download.
### Request Example
```javascript
GM_download({
url: 'https://example.com/file.zip',
name: 'downloaded_file.zip',
onload: () => console.log('Download complete!'),
onerror: (err) => console.error('Download failed:', err)
});
```
### Response Example
```json
{
"abort": "() => void"
}
```
```
--------------------------------
### GM_download with Options Object
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Use this method to download a URL to a local file by providing an options object. Most GM_xmlhttpRequest options are supported, including callbacks for download events.
```javascript
GM_download(options)
```
--------------------------------
### Update Menu Command In-Place
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Shows how to update an existing menu command in-place using its ID, or how to recreate commands if in-place updates are not supported.
```javascript
const id = 'status';
const inplace = id === GM_registerMenuCommand('Enabled', onClick, { id });
if (inplace) {
// supported: change the command in-place using the same `id`
GM_registerMenuCommand('Disabled', onClick, { id, title: 'Status' });
} else {
// not supported: recreate the commands
GM_unregisterMenuCommand('Enabled');
GM_unregisterMenuCommand('Foo');
GM_unregisterMenuCommand('Bar');
GM_registerMenuCommand('Disabled', onClick);
GM_registerMenuCommand('Foo', onClick2);
GM_registerMenuCommand('Bar', onClick3);
}
```
--------------------------------
### Project Structure
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/README.md
Illustrates the directory layout of the Violentmonkey project.
```tree
└── content
├── pages
└── posts # blog posts about Violentmonkey
```
--------------------------------
### List all values in storage
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Returns an array containing the keys of all values currently stored for the script.
```javascript
let arrayOfKeys = GM_listValues()
```
--------------------------------
### GM_setClipboard
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Sets data to the system clipboard.
```APIDOC
## GM_setClipboard
### Description
Sets data to system clipboard.
### Method Signature
```js
GM_setClipboard(data, type)
```
### Parameters
#### Path Parameters
- **data** (string) - Required - The data to be copied to system clipboard.
- **type** (string) - Optional - The MIME type of data to copy. Defaults to `'text/plain'`.
```
--------------------------------
### Register a Simple Keyboard Shortcut
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Use the register function to bind a key combination (e.g., 'c-i' for Ctrl+I) to a callback function.
```js
VM.shortcut.register('c-i', () => {
console.log('You just pressed Ctrl-I');
});
```
--------------------------------
### Add @violentmonkey/shortcut via @require
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Include the @violentmonkey/shortcut library in your script's meta block using the @require directive. Access exports via VM.shortcut.
```js
// ==UserScript==
// ...
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/shortcut@1
// ==/UserScript==
const { register } = VM.shortcut;
```
--------------------------------
### GM_download with Separate Parameters
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Use this method to download a URL to a local file by providing the URL and filename as separate parameters. Folders and subpaths are not supported for the filename.
```javascript
GM_download(url, name)
```
--------------------------------
### GM_download with separate parameters
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Downloads a URL to a local file using separate URL and name parameters.
```APIDOC
## GM_download(url, name)
### Description
Downloads a URL to a local file using separate URL and name parameters.
### Parameters
#### Path Parameters
- **url** (string) - Required - The URL to download.
- **name** (string) - Required - The filename to save to. Folders/subpaths aren't supported yet.
### Returns
- **object** - A control object with an `abort` function to cancel the download.
### Request Example
```javascript
GM_download('https://example.com/image.png', 'my_image.png');
```
### Response Example
```json
{
"abort": "() => void"
}
```
```
--------------------------------
### Disable and Enable All Key Bindings
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Temporarily disable all registered keyboard shortcuts using VM.shortcut.disable() and re-enable them later with VM.shortcut.enable().
```js
// Disable all key bindings temporarily
VM.shortcut.disable();
// Re-enable key bindings
VM.shortcut.enable();
```
--------------------------------
### Open URL in New Tab with Options
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Opens a URL in a new tab using an options object for detailed control over tab behavior like activation, pinning, and container.
```javascript
let tabControl = GM_openInTab(url, options)
```
--------------------------------
### GM_info
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves information about the current script and its environment.
```APIDOC
## GM_info
### Description
Retrieves information about the current script and its environment.
### Response
#### Success Response (200)
- **script** (object) - Information about the script.
- **version** (string) - The version of Violentmonkey.
- **script.uuid** (string) - The unique identifier of the script.
- **script.name** (string) - The name of the script.
- **script.namespace** (string) - The namespace of the script.
- **script.version** (string) - The version of the script.
- **script.author** (string) - The author of the script.
- **script.description** (string) - The description of the script.
- **script.homepage** (string) - The homepage of the script.
- **script.updateURL** (string) - The update URL of the script.
- **script.defaulturl** (string) - The default URL of the script.
- **script.iconURL** (string) - The icon URL of the script.
- **script.icon64URL** (string) - The 64x64 icon URL of the script.
- **script.matches** (string[]) - An array of match patterns for the script.
- **script.includes** (string[]) - An array of include patterns for the script.
- **script.excludes** (string[]) - An array of exclude patterns for the script.
- **script.runAt** (string) - The run at setting for the script.
- **script.grant** (string[]) - An array of granted APIs for the script.
- **script.require** (string[]) - An array of required scripts for the script.
- **script.resources** (object) - An object containing script resources.
- **script.unwrap** (boolean) - Whether the script is unwrapped.
- **script.originalCode** (string) - The original code of the script.
### Response Example
```json
{
"script": {
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"name": "My Script",
"namespace": "my.namespace",
"version": "1.0.0",
"author": "John Doe",
"description": "A sample script.",
"homepage": "http://example.com",
"updateURL": "http://example.com/update",
"defaulturl": "http://example.com/default",
"iconURL": "http://example.com/icon.png",
"icon64URL": "http://example.com/icon64.png",
"matches": ["http://*/*"],
"includes": [],
"excludes": [],
"runAt": "document-end",
"grant": ["GM_info"],
"require": [],
"resources": {},
"unwrap": false,
"originalCode": "// ==UserScript==\n// @name My Script\n// @namespace my.namespace\n// @version 1.0.0\n// @author John Doe\n// @description A sample script.\n// @homepage http://example.com\n// @updateURL http://example.com/update\n// @defaulturl http://example.com/default\n// @iconURL http://example.com/icon.png\n// @icon64URL http://example.com/icon64.png\n// @match http://*/*\n// @grant GM_info\n// ==/UserScript==\n\nconsole.log(GM_info)"
},
"version": "2.19.1"
}
```
```
--------------------------------
### Script Resources
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @resource key defines static resources accessible via GM_getResourceText and GM_getResourceURL. It includes a resource name and its URL.
```javascript
// @resource logo https://my.cdn.com/logo.png
// @resource text https://my.cdn.com/some-text.txt
```
--------------------------------
### Localized Script Description
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @description key provides a summary of the script and can be localized using a locale code suffix.
```javascript
// @description This script rocks.
// @description:zh-CN 这个脚本很棒!
```
--------------------------------
### Observe DOM Elements with @violentmonkey/dom and jQuery
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/observing-dom/index.mdx
Integrate jQuery with `VM.observe` for DOM manipulation. Ensure both `@violentmonkey/dom` and jQuery are included as script dependencies.
```javascript
VM.observe(document.body, () => {
// Find the target node
const $node = $('.profile');
if ($node.length) {
$node.prepend('
Profile
');
// disconnect observer
return true;
}
});
```
--------------------------------
### Handle Tab Close and Explicit Close
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Demonstrates how to set a callback for when the opened tab is closed and how to explicitly close the tab using the returned tabControl object.
```javascript
let tabControl = GM_openInTab(url);
tabControl.onclose = () => console.log('tab is closed');
tabControl.close();
```
--------------------------------
### Set multiple values in storage
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Writes multiple key-value pairs to the script's storage efficiently. Values must be JSON serializable.
```javascript
GM_setValues({ foo: 1, bar: [1, 2, 3] })
```
--------------------------------
### Script Versioning
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @version key specifies the script's version, composed of parts separated by dots. A @version is required for automatic updates.
```javascript
// @version 1.0
// @version 1.2a.3
```
--------------------------------
### Show Desktop Notification (Parameters) - Violentmonkey API
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Displays a desktop notification using separate parameters, compatible with Greasemonkey. This is a simpler way to show notifications when extensive configuration is not needed.
```javascript
GM_notification(text, title, image, onclick)
```
--------------------------------
### Observe DOM Elements with @violentmonkey/dom
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/observing-dom/index.mdx
Use `VM.observe` to watch for DOM changes and perform actions when a target element appears. Return `true` from the callback to automatically disconnect the observer after the first match.
```javascript
const disconnect = VM.observe(document.body, () => {
// Find the target node
const node = document.querySelector('.profile');
if (node) {
const h1 = document.createElement('h1');
h1.textContent = 'Profile';
node.prepend(h1);
// disconnect observer
return true;
}
});
// You can also disconnect the observer explicitly when it's not used any more
disconnect();
```
--------------------------------
### Register Menu Command with Shortcut
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx
Associate a keyboard shortcut with a GM_registerMenuCommand. The shortcut representation is included in the menu command name for clarity.
```js
const shortcut = 'c-g c-g';
const name = 'Good Game';
const handler = () => alert('Good Game!');
// Register menu command
const menuName = `${name} (${VM.shortcut.reprShortcut(shortcut)})`;
GM_registerMenuCommand(menuName, handler);
// Register shortcut
VM.shortcut.register(shortcut, handler);
```
--------------------------------
### Inject Script using Blob URL (Now)
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md
This is the current method used since Violentmonkey v2.8.15, employing Blob URLs to inject scripts. It resolves CSP issues on Firefox 58+ and is generally more robust.
```javascript
const b = new Blob([script], { type: 'text/javascript' });
const u = URL.createObjectURL(b);
const s = document.createElement('script');
s.src = u;
document.body.appendChild(s);
document.body.removeChild(s);
URL.revokeObjectURL(u);
```
--------------------------------
### Userscript Metadata Block
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/creating-a-userscript/index.md
The metadata block declares essential information about the script, such as its name, namespace, the URLs it should run on (@match), granted permissions (@grant), version, author, and a brief description. Ensure the @match directive correctly specifies the target URLs.
```javascript
// ==UserScript==
// @name New script
// @namespace Violentmonkey Scripts
// @match *://*/*
// @grant none
// @version 1.0
// @author -
// @description 3/8/2020, 8:42:28 PM
// ==/UserScript==
```
--------------------------------
### GM_registerMenuCommand
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Registers a command in the Violent Monkey popup menu, which can be invoked by the user.
```APIDOC
## GM_registerMenuCommand
Registers a command in Violentmonkey popup menu.
### Usage
```js
GM_registerMenuCommand('Text', onClick)
const id2 = GM_registerMenuCommand('Text2', onClick, { title: 'Two' })
const id3 = GM_registerMenuCommand('Text3', onClick, { autoClose: false })
```
### Parameters
- **caption** (string) - Required - This text will be shown in the popup menu.
- **onClick** (function) - Required - When the command is clicked in the menu, this function will run.
- **event** (MouseEvent | KeyboardEvent) - Optional, since VM2.13.1 - The event that activated the command, allowing checks for `event.button`, `event.shiftKey`, `event.key`, etc.
- **options** (object) - Optional, since VM2.15.9
- **id** (string) - Optional, since VM2.15.9 - Default: `caption` text (since VM2.16.2). Default in 2.15.9-2.16.1: a randomly generated string.
- **icon** (string) - Optional, since VM2.31.1 - URL of the icon.
- **title** (string) - Optional - A hint shown in the status bar when hovering the command.
- **autoClose** (boolean) - Optional, defaultValue: `true` - Whether to auto-close the popup after the user invoked the command.
### Returns
The command's `caption` (since VM2.12.5) or `id` (since VM2.15.9).
### Example
```js
const id = 'status';
const inplace = id === GM_registerMenuCommand('Enabled', onClick, { id });
if (inplace) {
// supported: change the command in-place using the same `id`
GM_registerMenuCommand('Disabled', onClick, { id, title: 'Status' });
} else {
// not supported: recreate the commands
GM_unregisterMenuCommand('Enabled');
GM_unregisterMenuCommand('Foo');
GM_unregisterMenuCommand('Bar');
GM_registerMenuCommand('Disabled', onClick);
GM_registerMenuCommand('Foo', onClick2);
GM_registerMenuCommand('Bar', onClick3);
}
```
```
--------------------------------
### Set System Clipboard - Violentmonkey API
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Copies specified data to the system clipboard. You can also specify the MIME type of the data being copied.
```javascript
GM_setClipboard(data, type)
```
--------------------------------
### Required Scripts
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @require key specifies the URL of another script that must be executed before the current one. Local files are not permitted.
```javascript
// @require https://my.cdn.com/jquery.js
```
--------------------------------
### Set a value in storage
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Sets a key-value pair in the script's storage. The value must be JSON serializable.
```javascript
GM_setValue(key, value)
```
--------------------------------
### Add Style Element
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Appends and returns a style element with the specified CSS code. Older versions might return a Promise-like object for compatibility.
```javascript
let styleElement = GM_addStyle(css);
```
--------------------------------
### Detect URL Changes with Navigation API or MutationObserver
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md
This snippet demonstrates how to detect URL changes using either the Navigation API or a MutationObserver. It sets up an event listener for 'navigatesuccess' if available, otherwise it falls back to observing DOM mutations to track URL changes. The `onUrlChange` function is called when a URL change is detected.
```javascript
if (self.navigation) {
navigation.addEventListener('navigatesuccess', onUrlChange);
} else {
let u = location.href;
new MutationObserver(() => u !== (u = location.href) && onUrlChange())
.observe(document, {subtree: true, childList: true});
}
function onUrlChange() {
if (!location.pathname.startsWith('/watch')) {
// deactivate();
return;
}
console.log('processing', location.href);
// activate();
}
```
--------------------------------
### Show Desktop Notification (Object) - Violentmonkey API
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Displays a desktop notification using the browser's notification API. This method accepts an options object for detailed configuration. It returns a control object with a `remove` function.
```javascript
let control = GM_notification(options)
```
--------------------------------
### Add a storage change listener
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Adds a listener that triggers a callback function when a specified storage value changes. Returns a listener ID for removal.
```javascript
let listenerId = GM_addValueChangeListener(name, callback)
```
--------------------------------
### Grant No Special APIs - @grant none
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
When no special APIs are needed, use '@grant none' to disable sandboxing and allow direct modification of global variables. This was the default behavior before Violentmonkey v2.32.0.
```javascript
// @grant none
```
--------------------------------
### Open URL in New Tab (Background)
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Opens a URL in a new tab, compatible with Greasemonkey's boolean option to control background opening. `true` opens in background.
```javascript
let tabControl = GM_openInTab(url, openInBackground)
```
--------------------------------
### GM_addElement
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Appends and returns an element with the specified attributes. This is primarily used to circumvent strict Content Security Policies that forbid adding inline code or style.
```APIDOC
## GM_addElement
*Since VM2.13.1*
Appends and returns an element with the specified attributes with the primary purpose of circumventing a strict `Content-Security-Policy` that forbids adding inline code or style.
```js
let element1 = GM_addElement(tagName, attributes);
let element2 = GM_addElement(parentNode, tagName, attributes);
```
### Parameters
* **parentNode?** (Node | Element | ShadowRoot) - Optional - The parent node to which the new node will be appended. It can be inside ShadowDOM: `someElement.shadowRoot`. When omitted, it'll be determined automatically: `document.head` for `script`, `link`, `style`, `meta` tags; `document.body` for other tags or when there's no ``; `document.documentElement` otherwise.
* **tagName** (string) - Required - A tag name like `'script'`.
* **attributes?** (object) - Optional - The keys are HTML attributes, not DOM properties, except `textContent` which sets DOM property `textContent`. The values are strings.
### Examples
```js
// using a private function in `onload`
let el = GM_addElement('script', { src: 'https://....' });
el.onload = () => console.log('loaded', el);
```
```js
// same as GM_addStyle('a { color:red }')
let el = GM_addElement('style', { textContent: 'a { color:red }' });
```
```js
// appending to an arbitrary node
let el = GM_addElement(parentElement.shadowRoot, 'iframe', { src: url });
```
### Notes
The element is returned immediately (synchronously). Invalid arguments will raise an exception, which can be caught using `try {} catch (e) {}`, just like standard DOM API `document.createElement`.
```
--------------------------------
### GM_getValues
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves multiple values for the current script from storage.
```APIDOC
## GM_getValues
### Description
Retrieves multiple values for the current script from storage.
### Method
1. **Using an array of keys.**
```js
let values = GM_getValues(['foo', 'bar'])
```
2. **Using an object.**
Each key is a name to read from storage, the value is the default to be used in the result if the key was not in storage.
```js
let values = GM_getValues({ foo: 1, bar: [2] })
```
### Parameters
#### Path Parameters
- **keys** (string[]) - Required - An array of keys to retrieve values for.
- **defaults** (Object) - Optional - An object where keys are the names to read from storage and values are the defaults to be used in the result if the key was not in storage.
### Response
#### Success Response (200)
- **values** (Object) - An object containing the retrieved key-value pairs.
### Response Example
```json
{
"foo": 123,
"bar": [1, 2, 3]
}
```
```
--------------------------------
### GM_setValues
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Writes multiple values to the current script's storage.
```APIDOC
## GM_setValues
### Description
Writes multiple values to the current script's storage.
### Method
```js
GM_setValues({ foo: 1, bar: [1, 2, 3] })
```
### Parameters
#### Path Parameters
- **data** (Object) - Required - Each `key:value` pair in the object will be stored individually. Must be JSON serializable.
### Request Example
```js
GM_setValues({
username: 'Bob',
preferences: {
theme: 'dark'
}
})
```
```
--------------------------------
### Grant Window Focus API - @grant window.focus
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
Enable the script to focus the current tab using window.focus(), even without prior user interaction. This feature was added in Violentmonkey v2.12.10.
```javascript
// @grant window.focus
```
--------------------------------
### Watch for URL Changes in SPA
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md
This snippet demonstrates how to manually trigger a check for URL changes within an SPA after the initial script has loaded. This is useful for scripts that need to react to client-side navigation.
```javascript
onUrlChange();
```
--------------------------------
### GM_listValues
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Returns an array of keys of all available values within this script.
```APIDOC
## GM_listValues
### Description
Returns an array of keys of all available values within this script.
### Method
```js
let arrayOfKeys = GM_listValues()
```
### Response
#### Success Response (200)
- **arrayOfKeys** (string[]) - An array of strings, where each string is a key stored for the current script.
### Response Example
```json
["username", "preferences", "lastLogin"]
```
```
--------------------------------
### GM_unregisterMenuCommand
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Unregisters a command that was previously registered to the Violent Monkey popup menu.
```APIDOC
## GM_unregisterMenuCommand
### Description
Unregisters a command which has been registered to Violentmonkey popup menu.
### Method Signature
```js
GM_unregisterMenuCommand(captionOrId)
```
### Parameters
#### Path Parameters
- **captionOrId** (string) - Required - The caption or id of the command to unregister. See [GM_registerMenuCommand](#gm_registermenucommand) for more info.
```
--------------------------------
### Script Icon
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @icon key specifies the URL for an icon to represent the script.
```javascript
// @icon https://my.cdn.com/icon.png
```
--------------------------------
### Inject Script using textContent (Before v2.8.15)
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md
This method was used in older versions of Violentmonkey to inject scripts by setting the textContent of a script element. It works on Chrome but fails on Firefox 57- with CSP limitations.
```javascript
const s = document.createElement('script');
s.textContent = script;
document.body.appendChild(s);
document.body.removeChild(s);
```
--------------------------------
### GM_getResourceURL
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves a blob: or data: URL of a resource from the metadata block. This function can return either a blob URL (default) or a data URL based on the `isBlobUrl` parameter.
```APIDOC
## GM_getResourceURL
Retrieves a `blob:` or `data:` URL of a resource from the metadata block.
```js
let blobUrl = GM_getResourceURL(name);
let blobOrDataUrl = GM_getResourceURL(name, isBlobUrl);
```
### Parameters
* **name** (string) - Required - Name of a resource defined in the [metadata block](../metadata-block/#resource).
* **isBlobUrl** (boolean) - Optional (since VM2.13.1, defaultValue: true) - If true, returns a `blob:` URL. If false, returns a `data:` URL.
### Notes
When setting this URL as `src` or `href` of a DOM element, it may fail on some sites with a particularly strict CSP that forbids `blob:` or `data:` URLs. The workaround in Chrome is to use `GM_addElement`, whereas in Firefox you'll have to disable CSP either globally via `about:config` or by using an additional extension that modifies HTTP headers selectively.
```
--------------------------------
### GM_setValue
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Sets a key/value pair for the current script to storage.
```APIDOC
## GM_setValue
### Description
Sets a key/value pair for the current script to storage.
### Method
```js
GM_setValue(key, value)
```
### Parameters
#### Path Parameters
- **key** (string) - Required - The unique name for `value` within this script.
- **value** (any) - Required - The value to be stored, which must be JSON serializable.
### Request Example
```js
GM_setValue('username', 'Alice')
```
```
--------------------------------
### Make a Cross-Origin Request with GM_xmlhttpRequest
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Use GM_xmlhttpRequest to make requests similar to XMLHttpRequest, but without same-origin policy restrictions. The `details` object configures the request, and event handlers can be provided to manage the response.
```javascript
let control = GM_xmlhttpRequest(details)
```
--------------------------------
### Localized Script Names
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @name key can be localized for different languages by appending a colon and the locale code, such as `@name:zh-CN` for Simplified Chinese.
```javascript
// @name Violentmonkey Script
// @name:zh-CN 暴力猴脚本
```
--------------------------------
### GM_notification
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Shows a desktop notification using the browser.notifications API. Can be called with an options object or separate parameters.
```APIDOC
## GM_notification
### Description
Shows a desktop notification using the [browser.notifications API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications).
### Method Signature (Object)
```js
let control = GM_notification(options)
```
### Parameters (Object)
#### Request Body
- **options** (object) - Required
- **text** (string) - Required - Main text of the notification.
- **title?** (string) - Optional - Title of the notification.
- **image?** (string) - Optional - URL of an image to show in the notification.
- **silent?** (boolean) - Optional - No sounds/vibrations when showing the notification. Only for Chromium-based browsers as of Aug 2023. Defaults to `false`.
- **tag?** (string) - Optional - Unique name of the notification, e.g. 'abc', same as the web Notification API. Names are scoped to each userscript. The purpose of a tagged notification is to replace an older notification with the same tag.
- **zombieTimeout?** (number) - Optional - Number of milliseconds to keep the notification after the userscript "dies". Defaults to `0`.
- **zombieUrl?** (string) - Optional - URL to open when a zombie notification is clicked.
- **onclick?** (function) - Optional - Callback when the notification is clicked by user.
- **ondone?** (function) - Optional - Callback when the notification is closed.
### Method Signature (Separate Parameters)
```js
GM_notification(text, title, image, onclick)
```
### Parameters (Separate Parameters)
#### Path Parameters
- **text** (string) - Required - Main text of the notification.
- **title?** (string) - Optional - Title of the notification.
- **image?** (string) - Optional - URL of an image to show in the notification.
- **onclick?** (function) - Optional - Callback when the notification is clicked by user.
### Response
#### Success Response (200)
As of VM2.12.8 returns a control object with the following properties:
- **remove** (function) - A function to remove the notification.
```
--------------------------------
### GM_getValue
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves a value for the current script from storage.
```APIDOC
## GM_getValue
### Description
Retrieves a value for the current script from storage.
### Method
```js
let value = GM_getValue(key, defaultValue)
```
### Parameters
#### Path Parameters
- **key** (string) - Required - The name for `value` to load.
- **defaultValue** (any) - Optional - The default value to return if no value exists in the storage.
### Response
#### Success Response (200)
- **value** (any) - The retrieved value from storage, or the default value if not found.
### Request Example
```js
let username = GM_getValue('username', 'Guest')
```
### Response Example
```json
"Guest"
```
```
--------------------------------
### Script Namespace
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
The @namespace key, combined with @name, uniquely identifies a userscript. It can be any string, often a homepage URL.
```javascript
// @namespace https://violentmonkey.github.io
```
--------------------------------
### Grant New GM API - @grant GM.getValue
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
Grant access to the newer GM.* API methods, such as GM.getValue. This syntax is available since Violentmonkey v2.12.10.
```javascript
// @grant GM.getValue
// @grant GM.setValue
```
--------------------------------
### Register Menu Command
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Registers a command in the Violent Monkey popup menu. The command is identified by its caption and an optional onClick handler.
```javascript
GM_registerMenuCommand('Text', onClick)
```
```javascript
const id2 = GM_registerMenuCommand('Text2', onClick, { title: 'Two' })
```
```javascript
const id3 = GM_registerMenuCommand('Text3', onClick, { autoClose: false })
```
--------------------------------
### Firefox Content Script Workaround with wrappedJSObject and exportFunction
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-into-context.md
Use this Firefox-specific workaround to access and expose webpage JavaScript objects from a content script. Ensure `exportFunction` is available and `unsafeWindow` is used if available, otherwise fallback to `window`.
```javascript
if (typeof exportFunction === 'function') {
const wnd = typeof unsafeWindow === 'object' ? unsafeWindow : window;
wnd.wrappedJSObject.foo = 1;
wnd.wrappedJSObject.bar = exportFunction(function myFancyApi(x) {
return cloneInto({ test: () => x }, wnd, { cloneFunctions: true });
});
}
```
--------------------------------
### GM_getResourceText
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Retrieves a text resource from the metadata block.
```APIDOC
## GM_getResourceText
### Description
Retrieves a text resource from the metadata block.
### Method
```js
let text = GM_getResourceText(name)
```
### Parameters
#### Path Parameters
- **name** (string) - Required - Name of a resource defined in the [metadata block](../metadata-block/#resource).
### Response
#### Success Response (200)
- **text** (string) - The content of the requested text resource.
### Request Example
```js
let config = GM_getResourceText('config.json')
```
### Response Example
```json
"{\"setting1\": \"value1\", \"setting2\": 123}"
```
```
--------------------------------
### Enable Top-Level Await with @top-level-await
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
Enable top-level await in your userscript to use await expressions outside of async functions. This is useful for waiting on external events or network data before the rest of your script executes. Avoid using it for essential dependencies; prefer @require or @resource for those.
```javascript
// @top-level-await
const data = await fetch('/api/data');
console.log(data);
```
--------------------------------
### Inject Script Directly with @unwrap
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx
Use the @unwrap directive to inject a script directly into the page's global scope without Violentmonkey's standard wrapper. This bypasses GM API access and is useful for interacting with global page variables or migrating from other extensions.
```javascript
// @unwrap
// @inject-into content
console.log('Script injected directly into global scope');
```
--------------------------------
### GM_addValueChangeListener
Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx
Adds a change listener to the storage and returns the listener ID.
```APIDOC
## GM_addValueChangeListener
### Description
Adds a change listener to the storage and returns the listener ID.
### Method
```js
let listenerId = GM_addValueChangeListener(name, callback)
```
### Parameters
#### Path Parameters
- **name** (string) - Required - The name of the observed variable.
- **callback** (function) - Required - A function to be called when the value changes. It receives `name`, `oldValue`, `newValue`, and `remote` as arguments.
- **name** (string) - The name of the observed variable.
- **oldValue** (any) - The old value of the observed variable (`undefined` if it was created).
- **newValue** (any) - The new value of the observed variable (`undefined` if it was deleted).
- **remote** (boolean) - `true` if modified by another tab, `false` otherwise.
### Request Example
```js
GM_addValueChangeListener('counter', (name, oldValue, newValue, remote) => {
console.log(`Value of ${name} changed from ${oldValue} to ${newValue}. Remote: ${remote}`);
});
```
```