On this page ▾
Popup and hub
When the overlay loads, a floating button appears in the bottom-right corner of your page. Click it to open the devtools in a panel on top of your app. You don't need a browser extension.
The floating button
Where it comes from
Importing the overlay adds the button. The first time the panel opens, it looks for the devtools server:
- If the overlay connected, it uses that path. When the path is
<base>ng-devtools/and a hub answers at<base>, it opens the hub. - Otherwise it checks for the hub at
/__devframes/, then for the devtools alone at/__ng-devtools/and/__devframes/ng-devtools/.
A path counts only when it answers with JSON. If nothing answers, the panel says No devtools server found and looks again the next time it opens.
Create it yourself
Most apps never call the popup API. To add the button without the overlay, call createDevtoolsPopup():
// src/main.ts
import {createDevtoolsPopup} from '@santoshyadavdev/ng-devtools/popup';
createDevtoolsPopup();
It adds the button and returns a handle with toggle() and destroy(). The panel finds the devtools server as described above. Importing the popup module in the browser also adds the button on its own, so calling it again returns the same handle.
To open a fixed page instead, pass src:
// src/main.ts
import {createDevtoolsPopup} from '@santoshyadavdev/ng-devtools/popup';
createDevtoolsPopup({src: '/__my-devtools/'});
A src given to a later call replaces the one before. showDevtools() adds the button when it is missing, and hideDevtools() removes it.
Match your app colors
The button reads CSS variables from your page. Set them on :root to match your app:
/* src/styles.css */
:root {
--ng-devtools-accent: #f5a524; /* button background */
--ng-devtools-accent-ink: #1c1300; /* button icon */
--ng-devtools-title: #f5a524; /* panel title and active dock mode */
}
The values above are the defaults.
The panel
Dock modes
You can drag only the floating panel. Switch modes from the buttons in the panel toolbar. The floating panel always stays inside the window: when the window shrinks, the panel moves and shrinks to fit, and grows back to its saved size when there is room again.
The button and the panel sit in the browser top layer, like a <dialog>, a popover or a CDK overlay (MatDialog, MatMenu, MatSelect). When one of those opens, the button and the panel move back above it. A modal <dialog> makes the rest of the page inert, so they stay under it until it closes.
Keyboard and mouse
| Action | How |
|---|---|
| Close the panel | Escape, outside a search box with text |
| Move the floating panel | Drag its toolbar |
| Reset the panel position | Double-click its toolbar |
| Move the button | Drag it, or focus it and use the arrow keys |
| Move the button further | Hold Shift with the arrow keys |
| Reset the button position | Double-click it |
In a search box that has text, Escape clears the box and leaves the panel open. Press it again to close the panel.
Saved layout
The panel saves its position, size and dock mode in localStorage under ng-devtools-popup, so it keeps its layout across reloads. Clear that key to reset it.
Theme
The panel follows the color scheme of the hub, which follows your system unless you pick light or dark in the hub. Without the hub, the panel follows your system. The popup frame around the panel switches with it and saves the last theme with the layout.
The hub
Docks in the side rail
When the page's server mounts the hub (/__devframes/), the button opens the whole hub. A side rail shows one dock per tool:
| Dock | Shows |
|---|---|
| Angular | Dashboard, Components, Routes, Signals, Injectors, Forms, Pipes, and SSR & HTTP |
| NgRx | The Store tab |
| Analog | The Analog tab, or a notice in apps that do not use Analog |
| Angular Native | Components, Signals, Injectors and Store for a connected Angular Native app, or a setup notice when none is connected |
| NativeScript | Setup steps for NativeScript apps |
| Capacitor | A Coming Soon placeholder |
Full-page viewer
The full-page viewer is at /__devframes/ on the same server. The hub is built on @devframes/hub, so other devframe tools can join the same rail.
Without the hub
Without the hub (for example the standalone CLI, or a panel mounted with initDevframe()), every tab sits in one tab bar. The Store tab is a regular tab there.
Deep links
Tab hashes
The URL hash selects a tab. Open /__devframes/ng-devtools/#tab=signals to land on the Signals tab. Switching tabs updates the hash, so you can copy the URL at any time.
| Tab | Hash |
|---|---|
| Dashboard | #tab=dashboard |
| Components | #tab=components |
| Routes | #tab=routes |
| Signals | #tab=signals |
| Injectors | #tab=injectors |
| Store | #tab=store |
| Forms | #tab=forms |
| Pipes | #tab=pipes |
| SSR & HTTP | #tab=network |
| Analog | #tab=analog |
Last tab
Without a hash, the panel opens the tab you used last in this browser tab. The Chrome extension and the popup reload the panel on every navigation, and the panel keeps its tab across those reloads. It saves the tab in sessionStorage, so another browser tab starts on the Dashboard. A hash wins over the saved tab, and a tab that is turned off falls back to the Dashboard.
Limits
A hash or a saved tab only works for a tab that exists when the panel opens. The Analog tab appears after the server confirms the app is an Analog app, so #tab=analog does not select it on load. Inside the Angular dock, the Store and Analog tabs live in their own docks.
Connection status
The panel header shows the state of the connection:
| Label | Meaning |
|---|---|
| Live | The panel is connected to the server. |
| Connecting… | The panel is trying to reach the server. |
| Disconnected | The server is gone. |
If the panel cannot reach the server, check that the dev server is running, then reload.
Tabs in the background
A browser tab in the background runs its timers about once a minute. The app page stops reading itself while its tab is hidden and tells the server, and the server keeps its last data instead of dropping it. The panel then says Tab in background, showing the last data. When you switch back, the page sends fresh data. If a hidden tab stops answering for 5 minutes, the server drops it.
Troubleshooting
disposeOverlay.
ng-devtools-popup key from localStorage and reload.
/__devframes/. Check that your server mounts initNgDevtoolsHub() or the Vite plugin on the default base. On a custom base, pass <base>ng-devtools/ to initOverlay.