diff --git a/CHANGELOG.md b/CHANGELOG.md
index eac3aa34e426..bf80db840060 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@
 
 - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
 
+Work in this release was contributed by @arturovt. Thank you for your contribution!
+
 ## 8.47.0
 
 - feat(v8/core): Add `updateSpanName` helper function (#14736)
diff --git a/dev-packages/e2e-tests/test-applications/angular-17/src/app/component-tracking/component-tracking.components.ts b/dev-packages/e2e-tests/test-applications/angular-17/src/app/component-tracking/component-tracking.components.ts
index d437a1d43fdd..1e43d5c6c096 100644
--- a/dev-packages/e2e-tests/test-applications/angular-17/src/app/component-tracking/component-tracking.components.ts
+++ b/dev-packages/e2e-tests/test-applications/angular-17/src/app/component-tracking/component-tracking.components.ts
@@ -6,7 +6,10 @@ import { SampleComponent } from '../sample-component/sample-component.components
   selector: 'app-cancel',
   standalone: true,
   imports: [TraceModule, SampleComponent],
-  template: `<app-sample-component [trace]="'sample-component'"></app-sample-component>`,
+  template: `
+  <app-sample-component [trace]="'sample-component'"></app-sample-component>
+  <app-sample-component trace></app-sample-component>
+  `,
 })
 @TraceClass({ name: 'ComponentTrackingComponent' })
 export class ComponentTrackingComponent implements OnInit, AfterViewInit {
diff --git a/dev-packages/e2e-tests/test-applications/angular-17/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/angular-17/tests/performance.test.ts
index 29c88a6108e2..03a715ce646c 100644
--- a/dev-packages/e2e-tests/test-applications/angular-17/tests/performance.test.ts
+++ b/dev-packages/e2e-tests/test-applications/angular-17/tests/performance.test.ts
@@ -191,7 +191,7 @@ test.describe('finish routing span', () => {
 });
 
 test.describe('TraceDirective', () => {
-  test('creates a child tracingSpan with component name as span name on ngOnInit', async ({ page }) => {
+  test('creates a child span with the component name as span name on ngOnInit', async ({ page }) => {
     const navigationTxnPromise = waitForTransaction('angular-17', async transactionEvent => {
       return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation';
     });
@@ -201,23 +201,36 @@ test.describe('TraceDirective', () => {
     // immediately navigate to a different route
     const [_, navigationTxn] = await Promise.all([page.locator('#componentTracking').click(), navigationTxnPromise]);
 
-    const traceDirectiveSpan = navigationTxn.spans?.find(
+    const traceDirectiveSpans = navigationTxn.spans?.filter(
       span => span?.data && span?.data[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] === 'auto.ui.angular.trace_directive',
     );
 
-    expect(traceDirectiveSpan).toBeDefined();
-    expect(traceDirectiveSpan).toEqual(
-      expect.objectContaining({
-        data: {
-          [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
-          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
-        },
-        description: '<sample-component>',
-        op: 'ui.angular.init',
-        origin: 'auto.ui.angular.trace_directive',
-        start_timestamp: expect.any(Number),
-        timestamp: expect.any(Number),
-      }),
+    expect(traceDirectiveSpans).toHaveLength(2);
+    expect(traceDirectiveSpans).toEqual(
+      expect.arrayContaining([
+        expect.objectContaining({
+          data: {
+            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
+            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
+          },
+          description: '<sample-component>', // custom component name passed to trace directive
+          op: 'ui.angular.init',
+          origin: 'auto.ui.angular.trace_directive',
+          start_timestamp: expect.any(Number),
+          timestamp: expect.any(Number),
+        }),
+        expect.objectContaining({
+          data: {
+            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
+            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
+          },
+          description: '<app-sample-component>', // fallback selector name
+          op: 'ui.angular.init',
+          origin: 'auto.ui.angular.trace_directive',
+          start_timestamp: expect.any(Number),
+          timestamp: expect.any(Number),
+        }),
+      ]),
     );
   });
 });
diff --git a/dev-packages/e2e-tests/test-applications/angular-19/.npmrc b/dev-packages/e2e-tests/test-applications/angular-19/.npmrc
new file mode 100644
index 000000000000..070f80f05092
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/angular-19/.npmrc
@@ -0,0 +1,2 @@
+@sentry:registry=http://127.0.0.1:4873
+@sentry-internal:registry=http://127.0.0.1:4873
diff --git a/dev-packages/e2e-tests/test-applications/angular-19/src/app/component-tracking/component-tracking.components.ts b/dev-packages/e2e-tests/test-applications/angular-19/src/app/component-tracking/component-tracking.components.ts
index d437a1d43fdd..a82e5b1acce6 100644
--- a/dev-packages/e2e-tests/test-applications/angular-19/src/app/component-tracking/component-tracking.components.ts
+++ b/dev-packages/e2e-tests/test-applications/angular-19/src/app/component-tracking/component-tracking.components.ts
@@ -3,10 +3,13 @@ import { TraceClass, TraceMethod, TraceModule } from '@sentry/angular';
 import { SampleComponent } from '../sample-component/sample-component.components';
 
 @Component({
-  selector: 'app-cancel',
+  selector: 'app-component-tracking',
   standalone: true,
   imports: [TraceModule, SampleComponent],
-  template: `<app-sample-component [trace]="'sample-component'"></app-sample-component>`,
+  template: `
+    <app-sample-component trace="sample-component"></app-sample-component>
+    <app-sample-component trace></app-sample-component>
+    `,
 })
 @TraceClass({ name: 'ComponentTrackingComponent' })
 export class ComponentTrackingComponent implements OnInit, AfterViewInit {
diff --git a/dev-packages/e2e-tests/test-applications/angular-19/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/angular-19/tests/performance.test.ts
index af85b8ffc405..c2cb2eca34b6 100644
--- a/dev-packages/e2e-tests/test-applications/angular-19/tests/performance.test.ts
+++ b/dev-packages/e2e-tests/test-applications/angular-19/tests/performance.test.ts
@@ -191,7 +191,7 @@ test.describe('finish routing span', () => {
 });
 
 test.describe('TraceDirective', () => {
-  test('creates a child tracingSpan with component name as span name on ngOnInit', async ({ page }) => {
+  test('creates a child span with the component name as span name on ngOnInit', async ({ page }) => {
     const navigationTxnPromise = waitForTransaction('angular-18', async transactionEvent => {
       return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation';
     });
@@ -201,23 +201,36 @@ test.describe('TraceDirective', () => {
     // immediately navigate to a different route
     const [_, navigationTxn] = await Promise.all([page.locator('#componentTracking').click(), navigationTxnPromise]);
 
-    const traceDirectiveSpan = navigationTxn.spans?.find(
+    const traceDirectiveSpans = navigationTxn.spans?.filter(
       span => span?.data && span?.data[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] === 'auto.ui.angular.trace_directive',
     );
 
-    expect(traceDirectiveSpan).toBeDefined();
-    expect(traceDirectiveSpan).toEqual(
-      expect.objectContaining({
-        data: {
-          [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
-          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
-        },
-        description: '<sample-component>',
-        op: 'ui.angular.init',
-        origin: 'auto.ui.angular.trace_directive',
-        start_timestamp: expect.any(Number),
-        timestamp: expect.any(Number),
-      }),
+    expect(traceDirectiveSpans).toHaveLength(2);
+    expect(traceDirectiveSpans).toEqual(
+      expect.arrayContaining([
+        expect.objectContaining({
+          data: {
+            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
+            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
+          },
+          description: '<sample-component>', // custom component name passed to trace directive
+          op: 'ui.angular.init',
+          origin: 'auto.ui.angular.trace_directive',
+          start_timestamp: expect.any(Number),
+          timestamp: expect.any(Number),
+        }),
+        expect.objectContaining({
+          data: {
+            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.angular.init',
+            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular.trace_directive',
+          },
+          description: '<app-sample-component>', // fallback selector name
+          op: 'ui.angular.init',
+          origin: 'auto.ui.angular.trace_directive',
+          start_timestamp: expect.any(Number),
+          timestamp: expect.any(Number),
+        }),
+      ]),
     );
   });
 });
diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts
index c347a5e19b2e..a5b9391e6ee4 100644
--- a/packages/angular/src/tracing.ts
+++ b/packages/angular/src/tracing.ts
@@ -1,3 +1,5 @@
+// eslint-disable-next-line @typescript-eslint/consistent-type-imports
+import { ElementRef } from '@angular/core';
 import type { AfterViewInit, OnDestroy, OnInit } from '@angular/core';
 import { Directive, Injectable, Input, NgModule } from '@angular/core';
 import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router';
@@ -235,10 +237,17 @@ export class TraceService implements OnDestroy {
   }
 }
 
-const UNKNOWN_COMPONENT = 'unknown';
-
 /**
- * A directive that can be used to capture initialization lifecycle of the whole component.
+ * Captures the initialization lifecycle of the component this directive is applied to.
+ * Specifically, this directive measures the time between `ngOnInit` and `ngAfterViewInit`
+ * of the component.
+ *
+ * Falls back to the component's selector if no name is provided.
+ *
+ * @example
+ * ```html
+ * <app-my-component trace="myComponent"></app-my-component>
+ * ```
  */
 @Directive({ selector: '[trace]' })
 export class TraceDirective implements OnInit, AfterViewInit {
@@ -246,13 +255,19 @@ export class TraceDirective implements OnInit, AfterViewInit {
 
   private _tracingSpan?: Span;
 
+  public constructor(private readonly _host: ElementRef<HTMLElement>) {}
+
   /**
    * Implementation of OnInit lifecycle method
    * @inheritdoc
    */
   public ngOnInit(): void {
     if (!this.componentName) {
-      this.componentName = UNKNOWN_COMPONENT;
+      // Technically, the `trace` binding should always be provided.
+      // However, if it is incorrectly declared on the element without a
+      // value (e.g., `<app-component trace />`), we fall back to using `tagName`
+      // (which is e.g. `APP-COMPONENT`).
+      this.componentName = this._host.nativeElement.tagName.toLowerCase();
     }
 
     if (getActiveSpan()) {