Switching between localhost, staging, and production should not be a manual URL-editing task.
If you are testing web apps all day, you probably do this constantly:
- Copy a production or staging URL.
- Replace the hostname with localhost.
- Keep the path.
- Keep the query string.
- Keep the hash.
- Hope you did not typo anything.
A tiny Chrome extension can remove that workflow completely.
What the extension does
The extension reads the current tab URL, detects which environment you are on, and lets you jump to another configured environment while preserving:
- path
- query string
- hash
- custom ports
- custom base paths
Example:
https://staging.example.com/products/42?tab=reviews#pricing
can become:
http://localhost:3000/products/42?tab=reviews#pricing
in one click.
Manifest V3 structure
The extension is deliberately small:
url-switcher/
??? manifest.json
??? popup.html
??? popup.js
??? popup.css
??? options.html
??? options.js
??? background.js
??? icons/
The manifest only needs two permissions:
{
"manifest_version": 3,
"name": "URL Environment Switcher",
"permissions": ["storage", "tabs"],
"action": { "default_popup": "popup.html" },
"options_page": "options.html",
"background": { "service_worker": "background.js" }
}
tabs is needed to read and update the active tab URL. storage is needed to save environment settings.
No host permissions are required because the extension does not inspect page content.
The switching algorithm
The core logic is simple:
- Read the current tab URL.
- Compare its origin with configured environment origins.
- Find the active environment.
- Strip the active environment base path.
- Build the target URL with the target origin plus the original path/query/hash.
- Navigate the tab.
The important detail is using URL.origin instead of string prefix matching.
const current = new URL(currentUrl);
const activeIndex = envs.findIndex(env => {
const envUrl = new URL(env.baseUrl);
return envUrl.origin === current.origin;
});
Origin matching avoids mistakes like treating localhost:3000 and localhost:3001 as the same environment.
Then preserve the rest:
const target = new URL(targetEnv.baseUrl);
const nextUrl = target.origin + remainingPath + current.search + current.hash;
chrome.tabs.update({ url: nextUrl });
Options page
The options page lets developers define their own environments:
- Localhost:
http://localhost:3000 - Staging:
https://staging.example.com - Production:
https://example.com
These settings are stored in chrome.storage.sync, so they follow the user across Chrome profiles where sync is enabled.
Why this is useful
This is not a complex extension. That is the point.
It removes a tiny repeated annoyance from web development. If you switch environments dozens of times a day, those tiny cuts add up quickly.
It is also a clean Manifest V3 learning project: popup UI, options page, storage, tab navigation, and service worker structure without frameworks or build tooling.
Source code
The full source is MIT licensed:
https://github.com/ttcd77/url-switcher
You can download the ZIP and load it unpacked in Chrome today. Chrome Web Store publishing is blocked for me until developer identity verification is available, so unpacked loading is the current zero-budget distribution path.
Disclosure: this article was drafted with AI assistance and manually checked before posting.
Top comments (0)