Вийшов Angular 20: розбираємося, що нового
Команда Angular випустила
Нові експериментальні API в Angular
Щоб краще працювати з асинхронними даними, команда Angular ще у версії 19 додала resource API, а в Angular 20 розширила цю можливість — тепер з’явилися resource streaming та httpResource.
Приклад: завантаження користувача
const userId: Signal<string> = getUserId(); const userResource = resource({ params: () => ({ id: userId() }), loader: ({ request, abortSignal }) => { return fetch(`users/${request.id}`, { signal: abortSignal }); }, });
Цей код автоматично підвантажує користувача, коли змінюється userId.
Приклад: стрімінг даних через WebSocket
@Component({ template: `{{ dataStream.value() }}` }) export class App { dataStream = resource({ stream: () => { return new Promise(resolve => { const resourceResult = signal({ value: [] }); this.socket.onmessage = event => { resourceResult.update(current => ({ value: [...current.value, event.data] })); }; resolve(resourceResult); }); }, }); }
Цей приклад показує, як працювати з потоковими даними — наприклад, із WebSocket. Кожне нове повідомлення додається у список, а UI оновлюється автоматично.
Приклад: httpResource для HTTP-запитів
@Component({ template: `{{ userResource.value() | json }}` }) class UserProfile { userId = signal(1); userResource = httpResource<User>(() => `https://example.com/v1/users/${this.userId()}` ); }
Тут кожна зміна userId автоматично тригерить новий HTTP-запит. API повертає об’єкт з усім необхідним: value
, isLoading
, headers
тощо.
Працює все на базі HttpClient, тому можна підключати інтерсептори:
bootstrapApplication(AppComponent, { providers: [ provideHttpClient( withInterceptors([loggingInterceptor, cachingInterceptor]) ), ], });
Zoneless
Angular 20 зробив великий крок до так званого zoneless-режиму, де зміни в UI відслідковуються без zone.js
. Це простіше, швидше і чистіше.
Додано:
- Підтримку обробки глобальних помилок у Node.js (SSR):
unhandledRejection
,uncaughtException
. - Глобальні слухачі помилок у браузері через
provideBrowserGlobalErrorListeners
/
Як підключити:
bootstrapApplication(AppComponent, { providers: [ provideZonelessChangeDetection(), provideBrowserGlobalErrorListeners(), ], });
Не забудьте прибрати zone.js
із angular.json
, якщо переходите на zoneless.
Стабільна серверна підтримка
Angular 20 зробив стабільними дві важливі фічі:
Інкрементальна гідратація (incremental hydration)
Завантажується лише те, що потрібно, а не весь DOM одразу:
import { provideClientHydration, withIncrementalHydration, } from '@angular/platform-browser'; provideClientHydration(withIncrementalHydration());
Рендеринг на рівні маршрутів
Тепер можна задавати, як рендерити окремі маршрути: на сервері (SSR), на клієнті (CSR) або заздалегідь (Prerender):
export const routeConfig: ServerRoute = [ { path: '/login', mode: RenderMode.Server }, { path: '/dashboard', mode: RenderMode.Client }, { path: '/product/:id', mode: RenderMode.Prerender, async getPrerenderParams() { const dataService = inject(ProductService); const ids = await dataService.getIds(); // ["1", "2", "3"] return ids.map(id => ({ id })); } } ];
Це дає змогу оптимізувати швидкість і UX кожного окремого маршруту.
Динамічне створення компонентів з директивами та байндингами
У версії 20 Angular нарешті дозволяє створювати компоненти динамічно — не просто з інпутами й аутпутами, а ще й з директивами та двосторонніми байндингами.
Приклад:
import { createComponent, signal, inputBinding, outputBinding, twoWayBinding } from '@angular/core'; const canClose = signal(false); const title = signal('My dialog title'); createComponent(MyDialog, { bindings: [ inputBinding('canClose', canClose), outputBinding<Result>('onClose', result => console.log(result)), twoWayBinding('title', title), ], directives: [ FocusTrap, { type: HasColor, bindings: [inputBinding('color', () => 'red')], }, ] });
Простими словами: можна створити компонент на льоту, передати йому дані, додати потрібні директиви — і все це без зайвої мороки.
Шаблони стали ближчими до JavaScript
Тепер Angular підтримує нові вирази прямо в шаблонах:
- Ступінь:
{{ n ** 2 }}
- Оператор in:
{{ name in person }}
Шаблонні рядки:
<div [class]="`layout col-${colWidth}`"></div>
Це робить шаблони зрозумілішими для тих, хто звик до звичайного JavaScript.
Краще діагностування помилок
Angular почав ловити типові помилки ще на етапі розробки:
- Використання
??
у невідповідному контексті - Забутий імпорт структурних директив (
@if
,@for
) - І коли ви передаєте функцію
trackFn
у@for
не викликаючи її
@for (user of users; track trackFn) { <!-- ... --> }
Такого роду дрібниці тепер виявляються автоматично.
Покращена підтримка host bindings
Тепер можна вмикати перевірку типів для host у компонентах — просто додайте:
"angularCompilerOptions": { "typeCheckHostBindings": true }
У версії 21 це буде вмикатися автоматично.
Тестування з Vitest
Angular офіційно експериментує з Vitest — сучасною альтернативою Karma. Підтримує watch mode, швидше працює, і взагалі набагато приємніший у використанні.
Щоб спробувати:
npm i vitest jsdom --save-dev
У angular.json:
"test": { "builder": "@angular/build:unit-test", "options": { "tsConfig": "tsconfig.spec.json", "buildTarget": "::development", "runner": "vitest" } }
А у тестах:
import { describe, beforeEach, it, expect } from 'vitest';
І все — можна запускати ng test
.
Material: кнопки стали ще кращими
Angular Material оновився відповідно до Material 3:
- Зʼявилась тональна кнопка (tonal button) — виглядає сучасніше і краще вписується в дизайн.
- Назви компонентів стали послідовнішими.
- Зʼявився новий селектор
matIconButton
— щоб чітко вказувати, що це кнопка з іконкою. - Обʼєднано MatButton і MatAnchor — більше не треба імпортувати їх окремо.
Більше контролю в MatDialog і Overlay
У MatDialog зʼявився параметр closePredicate
, який дозволяє вказати умови, за яких діалог можна закривати. Нарешті!
У Overlay — нові API, що краще працюють з tree-shaking
. Тобто, у фінальний бандл потрапляє тільки те, що реально використовується.
Плавні анімації — або їх повна відсутність
Angular тепер поважає системне налаштування prefers-reduced-motion
, що важливо для людей з чутливістю до руху.
А для повного вимкнення анімацій (наприклад, у тестах) можна використати спеціальний
Angular та ШІ
У новій версії зʼявився файл llms.txt
, який допомагає
Також відкрито розділ angular.dev/ai — тут гайди, приклади, best practices для інтеграції GenAI, Genkit, Vertex AI тощо.
Кінець епохи *ngIf і друзів
Все. Крапка. *ngIf
, *ngFor
, *ngSwitch
офіційно застарілі.
Angular ще у v17 представив новий синтаксис:
@if
,@for
,@switch
- Пишеться як у JavaScript
- Не потребує імпорту директив
- Працює швидше
- Краще типізується
Щоб перейти на новий стиль, просто виконайте:
ng generate @angular/core:control-flow
Ця команда автоматично замінить старі конструкції у шаблонах.
І наостанок — Angular отримає власного маскота 🐟
Так, тепер у Angular буде талісман. Від «щита з очима» до симпатичної рибки-ліхтарика — команда розглядає різні варіанти. Можна долучитись до обговорення: запропонувати ідею, проголосувати чи навіть придумати ім’я.



Як думаєте, який маскот ідеально підійшов би Angular? Кидайте фото в коментарі 🙃
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів