Repository navigation
Description
Which @angular/* package(s) are relevant/related to the feature request?
compiler, compiler-cli, core
Description
When I want to change something I see on the page, the slowest part isn't the edit itself (template/style HMR is great), it's finding where that element lives. I open the browser inspector, look at markup full of _ngcontent-* attributes, guess which component it belongs to, and then search for the file and the line in my editor.
Other ecosystems solve this with a "click an element, open it in your editor" tool (Svelte's inspector, Vue DevTools' open-in-editor, click-to-component for React). Angular doesn't have one, but most of the pieces are already in the framework:
- Add internal-only debugging attributes #58982 added
ɵɵattachSourceLocations, which puts adata-ng-source-location="src/app/foo.html@o:…,l:…,c:…"attribute on every template element. The PR description says it's aimed at internal tools but that "we may consider exposing this in dev mode in the future". - refactor(compiler-cli): add compiler option for enabling source locations #70303 added the
enableTemplateSourceLocationscompiler option (under the internal Bazel/g3 options). ng serveruns on Vite, which already exposes/__open-in-editor(thelaunch-editormiddleware used by Vite, Vue and Nuxt). It detects the running editor (VS Code, Cursor, WebStorm, Zed…) or uses theLAUNCH_EDITORenv variable, so Angular doesn't need to know anything about editors.
I wanted to see how far these get us, so I built a small prototype on a fresh ng new app (v22.2.0). I enabled the option in a tsconfig.dev.json used only by the development configuration. Then I added a ~120 line dev-only script: hold Alt and hover to see the component and file:line:col, Alt+click calls /__open-in-editor?file=<path>:<line>:<col> and the editor opens on that line.
Prototype: https://github.com/aminesbdev/angular-source-inspector (see src/dev/source-inspector.ts and tsconfig.dev.json).
It worked better than I expected. I checked the locations in headless Chrome, and each one lands on the exact tag: external templates (product-card.html:6:3 → <button class="buy">), inline templates (price-tag.ts:7:7 → the <strong> inside the template string), and projected content. The compiler's project-relative paths work as-is with /__open-in-editor, since it resolves them from the directory where ng serve runs. With a real click, my editor opened on the right line. I did have to set LAUNCH_EDITOR because launch-editor doesn't detect my editor yet, but that's a one-line fix on their side.
A few things I noticed along the way:
- Paths end up in production if you just turn it on. Putting
enableTemplateSourceLocationsintsconfig.app.jsonships every template path in the production bundle (about 450 bytes on a three-component app). I only avoided it with a separate tsconfig for the development configuration, which isn't something most people would think to do. - A component's host element points to the template where it's used, not to its own template. That's probably right for this use case, but a tool would likely want both. The component's own class location is already available through its debug info, but only via
ɵcmp. - I only tried a single-project workspace. In a multi-project workspace, the compiler's paths and the directory
/__open-in-editorresolves from might not match. /__open-in-editorcomes from Vite and isn't something the Angular CLI documents, so tooling built on it would want the CLI to keep it around.
Proposed solution
Roughly in this order:
- Make source locations safe to enable in dev: either the emitted instruction is dev-mode only, or the option is documented as a dev-only one. Then make the option public.
- Have
ng serveturn it on by default for development builds (that part would be an angular-cli issue, I can open it there). - Build tooling on top: an "Open in editor" action in Angular DevTools and/or an Alt+click overlay like the prototype. This could also start as a community package once the attribute is available.
I'm happy to help with any of this if you think it's worth doing. I'm especially interested in steps 1 and 3.
Alternatives considered
- Component debug info only (
ClassDebugInfo, already emitted in dev mode). This gives the component class file and line, which is useful as a fallback, but not the template or the specific element. Reading it also requiresɵcmp. - Chrome DevTools workspaces. They let you save edits back to files, but they don't tell you which component template an element comes from.
- Third-party tools could do this today by reading private fields, but that breaks easily. A dev-mode attribute emitted by the compiler is a much more stable base to build on.
Activity
aminesbdev commentedon Sep 27, 2026
I turned the prototype into a package, so it's easy to try on a real app:
It turns on
enableTemplateSourceLocationsfor the development configuration only and adds a provider that production builds drop entirely. Then hold Alt and click an element to open its template line in your editor.It's experimental since it relies on the undocumented option, and that's also where step 1 would help the most. The compiler already wraps the class debug info in an
ngDevModeguard (devOnlyGuardedExpression). Doing the same for the source locations instruction would make the option safe to turn on, with no separate tsconfig needed.https://github.com/aminesbdev/angular-source-inspector