Skip to content

Rickroller Solution


Project Structure
rickroller/
  manifest.json
  content-script.js
manifest.json
{
    "manifest_version": 3,
    "name": "Rickroller",
    "description": "Infuriate your enemy by rickrolling them with google search results.",
    "version": "1.0",
    "content_scripts": [
        {
            "js": [
                "content-script.js"
            ],
            "matches": [
                "https://www.google.com/search?*"
            ]
        }
    ]
}
content-script.js
const rickrollProbability = 0.5;
for (let link of document.links) {
    if (Math.random() < rickrollProbability) {
        link.setAttribute("href", "https://www.youtube.com/watch?v=dQw4w9WgXcQ");
    }
}

Explanation

Our goal is to modify the HTML of a page when it loads. Therefore, we'll want to use a content script. From the docs.

Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them, and pass information to their parent extension.

We'll start by setting up a minimal working example which we'll iterate upon.

Step 1: Set up content-script.js

Start by creating a file, content-script.js, so that your project structure looks like this.

Project Structure
rickroller/
  manifest.json
  content-script.js

In the file, write a single line of JavaScript that turns the background of the current page gray. This'll be a nice visual indicator that our content script is firing properly.

content-script.js
document.body.style.backgroundColor = "gray";

Lastly, modify manifest.json so that it knows to execute content-script.js.

manifest.json
{
    "manifest_version": 3,
    "name": "Rickroller",
    "description": "Infuriate your enemy by rickrolling them with google search results.",
    "version": "1.0",
    "content_scripts": [
        {
            "js": [
                "content-script.js"
            ],
            "matches": [
                "<all_urls>"
            ]
        }
    ]
}
  • "js": ["content-script.js"] tells Chrome to execute the JavaScript file content-script.js.
  • "matches": ["<all_urls>"] tells Chrome to execute the content script on all URLs. We'll restrict this to Google Search URLs later.

How do I know the arguments and format of manifest.json?
See the docs for manifest.json.

Step 2: Install the extension

To install your extension,

  1. Go to chrome://extensions (Or click Extensions > Manage Extensions)
  2. Click Load Unpacked
  3. Select the project directory, rickroller/

Load unpacked

To confirm it works, refresh the page and the background should turn gray. If it doesn't, you probably have a bug.

You can't modify the DOM of chrome://extensions

Make sure you're not testing your extension on chrome://extensions. Chrome prevents extensions from modifying the DOM of this page for security reasons.

Debugging

See here for tips on debugging chrome extensions.

Step 3: Restrict the URLs for which the content script fires

We don't want the content script to fire on every webpage; only Google Search results. To acheive this, we can set the matches argument in manifest.json to "https://www.google.com/search?*".

manifest.json
{
    "manifest_version": 3,
    "name": "Rickroller",
    "description": "Infuriate your enemy by rickrolling them with google search results.",
    "version": "1.0",
    "content_scripts": [
        {
            "js": [
                "content-script.js"
            ],
            "matches": [
                "https://www.google.com/search?*"
            ]
        }
    ]
}

For more details on match patterns, see here.

Updating your extension

Once you've updated and saved your code, you need to reload your extension for your changes to take effect.

Reload extension

At this point, the only page whose background should turn gray is any google search results page. (example ).

Step 4: Implement the rickrolling JavaScript code

Our last step is to implement the JavaScript code that randomly modifies links in the search results to be rickrolling booby traps.

content-script.js
// Assign probability that each link will be modified
// Set this between 0.05 and 0.10 for maximum frustration
const rickrollProbability = 0.5;

// Iterate over all links on the page
for (let link of document.links) {

    // If this link is randomly selected, update its href attribute
    if (Math.random() < rickrollProbability) {
        link.setAttribute("href", "https://www.youtube.com/watch?v=dQw4w9WgXcQ");
    }
}

Reload the extension and give it a final test before planting it onto your worst enemy's browser.