LinkRouter
Automatically route VS Code links to the right browser, profile, or private
browsing context.
LinkRouter is a VS Code extension for developers who use different browsers for
local projects, QA systems, client work, and personal accounts. Configure your
rules once, then open links normally from VS Code.
Requirements
- VS Code 1.85 or newer
- macOS, Windows, or Linux with a graphical desktop session
- At least one supported browser installed
The native browser launchers support the system default browser, Chrome,
Firefox, and Edge on all three platforms. Safari, Arc, Brave, Opera, and
Vivaldi launches currently require macOS.
Installation
Marketplace
- Open the VS Code Extensions view.
- Search for
LinkRouter.
- Select Install.
Local VSIX
If you received a .vsix file:
- Open the VS Code Extensions view.
- Select the
... menu.
- Choose Install from VSIX....
- Select the LinkRouter
.vsix file.
Quick Start
- Install LinkRouter.
- Open the Command Palette and run LinkRouter: Open Settings.
- Add rules to the generated
linkrouter.json file.
- Open a file containing a URL and Cmd/Ctrl+Click it.
Example configuration:
{
"defaultBrowser": "externalBrowser",
"debug": false,
"rules": [
{
"name": "Local projects",
"pattern": "http://*.test/**",
"browser": "firefox"
},
{
"name": "QA",
"pattern": "http://localhost:8080/**",
"browser": "chrome",
"profileDirectory": "Profile 2"
},
{
"name": "Guest frontend",
"pattern": "http://localhost:5173/**",
"browser": "chrome",
"private": true
}
]
}
Configuration files use strict JSON. Comments and trailing commas are not
supported.
Rules are evaluated from top to bottom. The first matching rule wins, so put
specific rules before broad rules:
{
"rules": [
{
"pattern": "http://localhost:8080/admin/**",
"browser": "chrome"
},
{
"pattern": "http://localhost:8080/**",
"browser": "firefox"
}
]
}
Opening Links
LinkRouter handles http:// and https:// URLs in:
- Editor files in any language
- Markdown links and HTML attributes
- Plain text and source-code strings
- URLs printed in the integrated terminal
You can open a URL in three ways:
- Cmd/Ctrl+Click the URL.
- Hover the URL and select Open with LinkRouter.
- Run LinkRouter: Open URL from the Command Palette.
Hovering a URL shows two actions:
- Open With... opens the URL in a browser you choose and bypasses rules.
- Open with LinkRouter applies your routing rules.
The Open With... picker keeps every supported browser available for manual
selection, marks browsers that are not detected on the current platform, and
adds configured named targets plus discovered Chrome profiles when available.
Choosing a target or profile opens that context directly and bypasses automatic
routing.
The picker is also a quick way to identify the profile directory needed by a
rule. A profile may appear as Google Chrome — Work, with a detail such as
Profile 2; use that directory value in profileDirectory:
{
"browser": "chrome",
"profileDirectory": "Profile 2"
}

Commands
| Command |
What it does |
LinkRouter: Open URL |
Routes the URL under the cursor, or a URL you enter, through your rules. |
LinkRouter: Open With... |
Opens a URL directly in a browser you choose, bypassing automatic routing. |
LinkRouter: Test Route |
Shows the rule and browser that would be selected without opening the URL. |
LinkRouter: Open Settings |
Opens or creates the LinkRouter configuration file. |

Configuration
LinkRouter reads linkrouter.json from these locations:
- Workspace:
.vscode/linkrouter.json in the current workspace.
- User: the extension's global storage directory.
- Built-in defaults when neither file exists.
When a workspace file exists, it completely replaces the user file. The two
files are not merged.
Run LinkRouter: Open Settings instead of finding the user file manually.
On macOS, its path is normally:
~/Library/Application Support/Code/User/globalStorage/linkrouter.link-router/linkrouter.json
The generated file includes schema validation and autocomplete. If you create a
workspace file manually, VS Code also validates it through the bundled schema.
Top-level settings
| Setting |
Values |
Default |
Description |
defaultBrowser |
externalBrowser, system, chrome, firefox, safari, edge, arc, brave, opera, vivaldi |
externalBrowser |
Browser used when no rule matches. |
targets |
Object |
{} |
Named browser contexts that rules can reuse. |
rules |
Array |
[] |
Ordered routing rules. |
debug |
true or false |
false |
Adds rule-evaluation details to the LinkRouter Output channel. |
externalBrowser uses the browser configured in VS Code's
workbench.externalBrowser setting. If that setting is not configured, the
operating system's default browser is used. Set system to always use the
operating system default.
Rule settings
{
"name": "QA server",
"pattern": "http://localhost:8080/**",
"browser": "chrome",
"profileDirectory": "Profile 2",
"private": false,
"args": ["--new-window"],
"enabled": true
}
| Field |
Required |
Description |
name |
No |
Friendly name shown by Test Route and diagnostics. |
pattern |
Yes |
URL glob pattern, such as https://*.example.com/**. |
browser |
One of browser or target |
Direct browser destination. |
target |
One of browser or target |
Name of a reusable context from targets. |
profileDirectory |
No |
Internal Chromium profile directory, such as Default or Profile 2. |
private |
No |
Opens a private/incognito window where supported. |
args |
No |
Additional browser launch arguments. |
enabled |
No |
Set to false to skip a rule without deleting it. Defaults to true. |
Invalid rules are skipped safely and reported in the LinkRouter Output channel.
Invalid JSON is ignored and does not crash the extension.
Named browser targets
Use targets for browser contexts that several rules share. A target defines
the browser and its default profile/private/custom-argument options; a rule can
reference it with target:
{
"targets": {
"qa": {
"browser": "chrome",
"profileDirectory": "Profile 2"
},
"personal": {
"browser": "firefox"
}
},
"rules": [
{
"name": "QA server",
"pattern": "http://localhost:8080/**",
"target": "qa"
},
{
"name": "Personal web",
"pattern": "https://example.com/**",
"target": "personal"
}
]
}
Each rule must use exactly one of browser or target. A rule containing
both is rejected instead of relying on an implicit precedence. A target's
profile, private mode, and custom arguments may be overridden by specifying
that field directly on the referencing rule. Targets are defined separately
in each effective configuration file; a workspace file replaces the user file
and does not merge its targets.

Browser Support
The browser names below are the values used in configuration files:
| Browser |
Platforms |
Private mode |
Profile directory |
Google Chrome (chrome) |
macOS, Windows, Linux |
private: true uses incognito |
Supported with profileDirectory |
Firefox (firefox) |
macOS, Windows, Linux |
private: true uses a private window |
Not supported by the command line |
Safari (safari) |
macOS |
Unsupported; opens a normal window with a warning |
Unsupported |
Microsoft Edge (edge) |
macOS, Windows, Linux |
private: true uses InPrivate |
Supported with profileDirectory |
Arc (arc) |
macOS |
Unsupported; opens a normal window with a warning |
Spaces are not mapped to profileDirectory |
Brave (brave) |
macOS |
private: true uses incognito |
Supported with profileDirectory |
Opera (opera) |
macOS |
Unsupported; opens a normal window with a warning |
Unsupported |
Vivaldi (vivaldi) |
macOS |
private: true uses incognito |
Supported with profileDirectory |
System Default (system) |
macOS, Windows, Linux |
Not applicable |
Not applicable |
When a browser cannot honor a requested option, LinkRouter warns in the Output
channel and opens the closest supported context instead of passing a meaningless
argument.
If a browser itself is not supported on the current operating system, LinkRouter
reports the platform limitation instead of attempting an unverified launch.
Browser availability in Open With... is advisory. On Windows, LinkRouter
checks common installation paths, Windows App Paths registry entries, and
executables available through where.exe. On Linux, it checks the same browser
commands used by the launcher through PATH. Flatpak and Snap browser
discovery is not currently included.

Browser Profiles
Chrome, Edge, Brave, and Vivaldi use internal profile directory identifiers. The
visible profile name is not always the value LinkRouter needs:
Default
Profile 1
Profile 2
Profile 3
Use the browser's profile diagnostics page to find the correct directory. Paste
one of these URLs into the matching browser's address bar:
| Browser |
Profile page |
Fallback page |
| Google Chrome |
chrome://profile-internals |
chrome://version |
| Microsoft Edge |
edge://profile-internals |
edge://version |
| Brave |
brave://profile-internals |
brave://version |
| Vivaldi |
vivaldi://profile-internals |
vivaldi://version |
| Firefox |
about:profiles |
Not applicable |
| Opera |
opera://profile-internals |
opera://about |
On a profile diagnostics page, find Profile Path. Use only the final
directory name from that path, for example Profile 2, not the full path.
When Chrome is installed on macOS, Open With... can read Chrome's local
profile metadata and show entries such as Google Chrome — Work. The picker
passes the discovered directory identifier automatically. LinkRouter never
writes to Chrome's profile files; if metadata cannot be read, the normal Chrome
entry remains available.
Chrome profile metadata discovery is currently available on macOS only. On
Windows and Linux, the normal browser entry remains available and
profileDirectory can be configured manually.
Some browser versions keep internal profile diagnostics behind an internal
debugging setting. If the page says internal debugging is disabled, temporarily
enable internal debugging using the browser's own instructions, inspect and copy
the profile directory, then disable internal debugging again. Do not leave
internal debugging enabled during normal browsing.
Firefox's about:profiles page can show Firefox profiles, but Firefox does not
provide a command-line equivalent that LinkRouter can use for profileDirectory.
Safari does not expose a compatible profile directory. Arc uses Spaces instead
of standard Chromium profile directories.
Private Browsing
Use private: true in a rule:
{
"pattern": "http://localhost:5173/**",
"browser": "chrome",
"private": true
}
LinkRouter translates this to the appropriate browser behavior, such as Chrome
incognito, Firefox private window, or Edge InPrivate. Unsupported browsers show
a warning and open a normal window.
Workspace Configuration
Use a workspace file when a project needs different browser rules from your
other projects:
{
"defaultBrowser": "externalBrowser",
"rules": [
{
"name": "Client A",
"pattern": "http://*.client-a.test/**",
"browser": "chrome",
"profileDirectory": "Profile 2"
}
]
}
Save it as .vscode/linkrouter.json. Workspace configuration is useful for
client projects, localhost ports, authenticated sessions, and QA profiles.
Remember that the workspace file replaces the user file completely.
Diagnostics
Open View -> Output, then select LinkRouter.
With debug: true, the Output channel shows the URL, rule count, each rule's
match result, selected browser, profile, and private mode. Query strings are
masked in logs so tokens and credentials are not exposed.
If a browser cannot be launched, LinkRouter shows an actionable error with
Use System Default and Open Settings options where applicable.
Troubleshooting
| Problem |
Solution |
| Browser does not open |
Confirm the browser is installed. Check the LinkRouter Output channel and use the System Default fallback. |
| Wrong rule matched |
Rules are first-match-wins. Move the more specific rule above the broader rule, or run Test Route. |
| Profile is not applied |
Use the internal directory identifier from the browser's profile page, such as Default or Profile 2. |
| Profile page is disabled |
Temporarily enable the browser's internal debugging setting, inspect the profile, then disable it again. |
| Two browsers open for one click |
Disable VS Code's editor.links setting and try again. VS Code's built-in link detector can overlap with LinkRouter's link. |
| URL is not clickable |
LinkRouter supports http and https URLs in saved files and the integrated terminal. Untitled buffers and other schemes are not captured. |
| Workspace rules are ignored |
Confirm the file is exactly .vscode/linkrouter.json. It replaces, rather than merges with, the user file. |
Settings in settings.json are ignored |
LinkRouter uses linkrouter.json. Run LinkRouter: Open Settings and move your rules there. |
| Windows or Linux launch fails |
Use Chrome, Firefox, Edge, or System Default on these platforms, and confirm the browser is installed and available to the platform launcher. |