DEV Community

Thomas Ledoux
Thomas Ledoux

Posted on • Originally published at thomasledoux.be

Creating a Chrome extension to convert the URL to use localhost in 1 click

Why?

Often when I'm working on a project, I get bug reports of issues happening on production/acceptance environments with a URL pointing to the matching environment. The problem is that I have to copy the URL, remove the domain and paste it in my local environment and port to reproduce the issue. This is a tedious process, so I decided to create a Chrome extension to automate this.

How?

I started out by creating a manifest.json file, which is required for every Chrome extension. This file contains the name, version, description, icons, permissions, etc. of the extension.

{
  "manifest_version": 3,
  "name": "Convert to localhost",
  "description": "Convert your current URL to localhost",
  "version": "0.0.1",
  "action": {
    "default_popup": "convert-to-localhost.html",
    "default_icon": "128x128.png"
  },
  "options_ui": {
    "page": "options.html",
    "open_in_tab": false
  },
  "permissions": ["tabs", "storage"],
  "icons": {
    "16": "16x16.png",
    "32": "32x32.png",
    "48": "48x48.png",
    "128": "128x128.png"
  }
}
Enter fullscreen mode Exit fullscreen mode

The action property is used to define the popup that is shown when you click on the extension icon. The options_ui property is used to define the options page of the extension. The permissions property is used to define which permissions the extension needs. In this case, we need the tabs permission to get the current URL and the storage permission to store the user's settings. The icons property is used to define the icons of the extension.
In the action's HTML I reference the JavaScript file which I use to execute the logic of the extension.
The port and the flag if HTTPS should be used come from the options of the extension (more on that below).
It also displays the sentence "Converted URL to localhost" to give some feedback to the user.

<html>
  <body>
    <h1>Converted URL to localhost</h1>
    <script src="convert-to-localhost.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The JavaScript itself is also quite simple:

  • get the currently active tab
  • get the URL from the tab and create a URL object from it, so we can read the pathname (the part we need) later
  • get the port from the user's settings and replace the domain with http${secure ? 's' : ''}://localhost:${port} and update the tab with the new URL.
(async () => {
  let queryOptions = { active: true, currentWindow: true };
  let [tab] = await chrome.tabs.query(queryOptions);
  const url = new URL(tab.url);
  const port = (await chrome.storage.sync.get("port")).port;
  const secure = (await chrome.storage.sync.get("secure")).secure;
  chrome.tabs.update({
    url: `http${secure ? "s" : ""}://localhost:${port ?? "3000"}${
      url.pathname
    }`,
  });
})();
Enter fullscreen mode Exit fullscreen mode

The options page is a simple HTML page with a form to set the port. The port is stored in the storage of the extension, so it's persisted between sessions.

<html>
  <body>
    <form>
      <label for="port">Port:</label>
      <input type="number" id="port" name="port" />
      <br />
      <label for="secure">HTTPS:</label>
      <input type="checkbox" id="secure" name="secure" />
      <button id="save" type="submit">Save</button>
    </form>
    <script src="options.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The JavaScript for the options page is only contains a few lines do to:

  • on load, get the port and secure from the storage and set the value of the input to the port and secure checkbox
  • on submit, get the value of the inputs and store them in the storage
// Saves options to chrome.storage
const saveOptions = () => {
  const port = document.getElementById("port").value;
  const secure = document.getElementById("secure").checked;
  chrome.storage.sync.set({ port, secure });
  window.close();
};

// Restores select box and checkbox state using the preferences
// stored in chrome.storage.
const restoreOptions = async () => {
  const syncItems = await chrome.storage.sync.get(["port", "secure"]);
  console.log(syncItems);
  document.getElementById("port").value = syncItems.port ?? "3000";
  document.getElementById("secure").checked = syncItems.secure;
};

document.addEventListener("DOMContentLoaded", restoreOptions);
document.getElementById("save").addEventListener("click", saveOptions);
Enter fullscreen mode Exit fullscreen mode

Once the code was ready, the time had come to start testing it in Chrome. To do this, you have to go to chrome://extensions/, enable developer mode and click on "Load unpacked". Then you can select the folder containing the extension and it will be loaded in Chrome. Now you can test the extension by clicking on the icon and setting the port in the options page.

When you change the source code, you do have to reload the extension by clicking the refresh icon on the extension in chrome://extensions/.
Publishing to the Chrome store wasn't really something I wanted to do for this extension, so that's not covered in this article.
Hope this was useful to you!

Source code can be found on GitHub.

Top comments (2)

Collapse
 
shrihari profile image
Shrihari Mohan

Hey nice one , why you didn't publish it ?

Collapse
 
thomasledoux1 profile image
Thomas Ledoux

I have published it, but it isn’t approved yet…