LinkRouter
Automatically route VS Code links to the right browser, profile, or private
browsing context.
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:
{
"$schema": "",
"defaultBrowser": "system",
"debug": false,
"rules": [
{
"name": "Local projects",
"pattern": "http://*.test/**",
"browser": "firefox"
},
{
"name": "QA",
"pattern": "http://localhost:8080/**",
"browser": "chrome",
},
{
"name": "Guest frontend",
"pattern": "http://localhost:5173/**",
"browser": "chrome",
"private": true
}
]
}
Rules are evaluated from top to bottom. The first matching rule wins, so put
specific rules before broad rules:
Opening Links
You can open a supported link in three ways:
Configuration
LinkRouter reads linkrouter.json from these locations:
- Workspace:
.vscode/linkrouter.json in the current workspace.
- User: the extension's global storage directory.
When a workspace file exists, it completely replaces the user file. The two
files are not merged.
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.
For an unmatched local file:// URI, LinkRouter always uses system so the
operating system's associated file application is selected, regardless of the
web-browser 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. |
Local files
LinkRouter also detects local file:// URIs in saved files and the integrated
terminal. Unmatched local files open with the operating system's associated
application. An explicit browser rule can open a file URI in that browser:
{
"name": "Preview local PDF in Chrome",
"pattern": "file:///Users/me/Documents/**/*.pdf",
"browser": "chrome"
}
Use absolute local URIs such as file:///Users/me/file.pdf or
file:///C:/Users/me/file.pdf. Remote file shares (file://server/share/...)
are not supported. File patterns match the URI form, so spaces must be encoded
as %20. All configured browser IDs can be used as explicit file destinations;
browser-specific profile and private-mode options retain their normal support
limitations.
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
The picker (on hover -> open with) 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:
Use the browser's profile diagnostics page to find the correct directory for chromium based browsers: {browser}://profile-internals.
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.
{
"name": "QA",
"pattern": "http://localhost:8080/**",
"browser": "chrome",
"profileDirectory": "Profile 2"
}
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.
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.
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. |
In the Explorer, right-click a local file and select LinkRouter: Open With
System Default to open it with the operating system's associated application.
This action is intentionally available only for files, not folders, and is not
shown in the Command Palette.
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.
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.
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, https, and local file URLs in saved files and the integrated terminal. Untitled buffers, remote file shares, 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. |