Key Updates and Features

This guide outlines the most significant changes arriving with Angular 17, along with resources to help you understand each one:

  • New declarative control flow syntax
  • Deferred loading blocks
  • Support for the View Transitions API
  • Ability to pass @Component.styles as a string
  • Lazy-loadable animations code
  • Compatibility with TypeScript 5.2

Other noteworthy points:

  • The core Signal API has reached a stable state (PR)
  • Signal-based components are still in development and won't be included in Angular 17
  • Support for Node.js v16 has been dropped; the minimum now is v18.13.0 (PR)
  • Esbuild is anticipated to become the default builder, with Vite serving as the default dev server

New Declarative Control Flow

RFC: Built-In Control Flow

Angular 17 introduces a fresh template control block syntax that offers a more declarative approach to control flow. This includes blocks for:

  • Conditional rendering (@if, @else, @switch, @case, and @default)
  • Iterating over collections with @for, and providing a fallback with the @empty block

A key advantage of these new blocks is their potential to enable zoneless applications when combined with Signals.

Here's a simple example to illustrate the usage. A checkbox is bound to the isChecked signal, which defaults to true. This means the checkbox starts checked, and the content inside the @if block is displayed:

<div>
  <input #checkbox type="checkbox" [checked]="isChecked()" (change)="isChecked.set(checkbox.checked)" id="checkbox"/>
</div>
<div>
@if (isChecked()) {
  <span>Checked</span>
} 
@else {
  <span>Not checked</span>
}
</div>
Enter fullscreen mode Exit fullscreen mode

The instruction @if (logical_expression) { is used to define an @if block based on a logical condition. Here, the isChecked() signal acts as that condition since it returns a boolean.

An @else block has been added, which takes over rendering when the condition in the @if block is false—in this case, when the isChecked() signal becomes false. Unchecking the box causes Angular to show the content within the @else block.

For a detailed walkthrough of every control block type (@if, @else, @switch, @case, @default, @for, @empty), refer to this guide: Angular v17 feature: new control flow syntax


Deferred Loading Blocks

RFC: Deferred Loading

Angular 17 elevates lazy-loading with the introduction of the @defer control block. This block allows for the content within it to be loaded lazily, and this extends to all its dependencies, including components, directives, and pipes. For a complete guide on using various deferred blocks, see: New Angular 17 feature: deferred loading


View Transitions API Support

Official docs: withViewTransitions

PR: feat(router): Add feature to support the View Transitions API

This update introduces support for the View Transitions API, which simplifies the process of creating animations during DOM state changes. Netanel Basal demonstrates how to leverage view transitions in Angular in his article.


Passing @Component.styles as a String

Official docs: Component.styles

PR: feat(core): support styles and styleUrl as strings

It is now possible to provide CSS rules as a string directly in the styles property of the @Component decorator:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './app.component.html',
  styles: `/* 👈 */
h3 {
  background-color: red; 
}
`
})
export class AppComponent { }
Enter fullscreen mode Exit fullscreen mode

Lazy-Loadable Animations

PR: feat(animations): Provide a way to lazy load the animations

The new provideLazyLoadingAnimations() function allows the animations code to be loaded on demand:

bootstrapApplication(AppComponent, {
  providers: [
    provideAnimationsAsync(),
    // ...
  ],
}).catch((err) => console.error(err));
Enter fullscreen mode Exit fullscreen mode

By opting into provideLazyLoadingAnimations(), you can reduce the main bundle size by roughly 16Kb, as the animation code is fetched only when needed.


TypeScript 5.2 Support

PR: feat(core): support TypeScript 5.2

Daniel Rosenwasser highlights the most notable new TS features in his announcement (Announcing TypeScript 5.2):

  • using Declarations and Explicit Resource Management
  • Decorator Metadata
  • Named and Anonymous Tuple Elements
  • Easier Method Usage for Unions of Arrays
  • Copying Array Methods
  • symbols as WeakMap and WeakSet Keys
  • Type-Only Import Paths with TypeScript Implementation File Extensions
  • Comma Completions for Object Members
  • Inline Variable Refactoring
  • Clickable Inlay Parameter Hints
  • Optimized Checks for Ongoing Type Compatibility

About the Author

My name is Gergely Szerovay, and I lead a frontend development chapter. I'm passionate about teaching and learning Angular, and I stay up-to-date by consuming a wide variety of Angular-related content—articles, podcasts, conference talks, and more.

I started the Angular Addict Newsletter to share the best resources I discover each month, catering to both seasoned developers and beginners.

I also run a publication called—you guessed it—Angular Addicts, a curated collection of the most informative and interesting resources I find. Feel free to reach out if you're interested in contributing as a writer.

Let's learn Angular together! Subscribe here 🔥

Follow me on Substack, Medium, Dev.to, Twitter, or LinkedIn for more Angular insights!