Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 22
cache: npm

- name: Install dependencies
Expand Down
25 changes: 25 additions & 0 deletions VERSIONING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Versioning

## Strategy
Angular Tips follows the same major versioning as Angular itself.

`/docs` folder contains documentation for the latest supported version of Angular.

`/versioned_docs` folder contains documentations for all previously supported versions of Angular.

When a new version of Angular is released, a new version of Angular Tips is created. The `docs` folder is copied for archiving purposes into `versioned_docs/version-vX` folder, where `X` is the previous major version number. `docs` folder then becomes the documentation for the new version of Angular and its content is updated accordingly.

## Create a new version
To create a new version of Angular Tips:

1. Run: `npm run docusaurus docs:version <previous_version>`
2. Replace occurences of previous version with the new version number in `docs` folder, especially:
- Links to Angular doc: `https://vX.angular.dev`
- Links to Angular Material doc: `https://vX.material.angular.dev`
- [Getting started > Angular Version](./docs/getting-started.md#angular-version)
3. Update [docusaurus.config.ts](./docusaurus.config.ts):
- Set `presets > docs > versions > current > label` to the new version number.
- Add a new entry in `presets > docs > versions` for the previous version.
4. Delete `draft: true` pages in the new `versioned_docs/version-vX` folder if any.
5. Test the new version locally and make sure it builds correctly.
6. Commit and push the changes.
9 changes: 9 additions & 0 deletions docs/component/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ forcing you to override them in several places.
}
```

**Do** use style binding instead of `ngStyle` directive.
- ❌ `[ngStyle]="{ 'width': '200px' }"`
- ✅ `[style]="{ 'width': '200px' }"`
- ✅ `[style.width.px]="200"`

## Global styles

**Do** split global styles in partial SCSS files.
Expand Down Expand Up @@ -210,6 +215,10 @@ While it's not a bad thing to use a CSS framework, it shouldn't be automatic. Th

✅ **[Tailwind CSS](https://tailwindcss.com/)**: utility-first CSS framework that provides low-level utility classes to build custom designs.

:::note
Since Angular v21, Tailwind CSS is natively supported and integrated with the Angular CLI, see [Angular guide](https://v21.angular.dev/guide/tailwind).
:::

✅ **[Bootstrap](https://getbootstrap.com/)**: CSS framework that provides a set of pre-designed components and utilities.

❌ **[PrimeFlex](https://primeflex.org/)**: project has stopped and no longer receive development or maintenance.
2 changes: 1 addition & 1 deletion docs/component/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ It also indicates that the component does not have projectable content.
```

:::tip
You can run the [schematic migration](https://angular.dev/reference/migrations/control-flow) to automatically replace directives above by control flow syntax.
You can run the [schematic migration](https://v21.angular.dev/reference/migrations/control-flow) to automatically replace directives above by control flow syntax.
:::

**Do** use class binding instead of `ngClass` directive.
Expand Down
4 changes: 2 additions & 2 deletions docs/component/typescript-class.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class UserPage {
**Do** use `input()` signal and `output()` function instead of `@Input()` and `@Ouput()` decorators.

:::tip
You can run [schematic migrations](https://angular.dev/reference/migrations) to automatically transform decorators to signals.
You can run [schematic migrations](https://v21.angular.dev/reference/migrations) to automatically transform decorators to signals.
:::

**Do** type inputs and outputs.
Expand Down Expand Up @@ -140,7 +140,7 @@ You can initialize your component inside the `constructor` instead of the `ngOnI
:::

:::warning Exceptions
Because Angular v20 is not completely signal-based yet, you will need to rely on lifecycle hooks in some cases, for example:
Because Angular v21 is not completely signal-based yet, you will need to rely on lifecycle hooks in some cases, for example:
- Initializing a form
- Accessing route data
- ...
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To submit a pull request:

When adding a new tip:
- It must be Angular related.
- It must add value to the [official Angular documentation](https://angular.dev/).
- It must add value to the [official Angular documentation](https://v21.angular.dev/).
- It must follow the [vocabulary](./getting-started.md#vocabulary).
- If possible, provide bad and good examples.
- Bad examples must be prefixed with "❌"
Expand Down
35 changes: 27 additions & 8 deletions docs/form.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ sidebar_position: 4
---
# Form

Forms are a fundamental part of most web applications, enabling users to input data, submit information, and interact with your application. Angular provides two primary approaches to handling forms, each with robust solutions for validation, data binding, and state management, designed to address different use cases and levels of complexity.

[Template-Driven form](#template-driven-forms) is the simplest approach that relies on directives in the template, suitable for simple forms with minimal complexity.

[Reactive form](#reactive-forms) is a more structured and flexible solution, but verbose, it is ideal for complex forms with programmatic control.

:::warning
Both approaches are expected to be superseded by [Signal Forms](#signal-forms) in future Angular versions, which will leverage Angular's signal-based reactivity system for improved performance and developer experience.
:::

## General guidelines

**Avoid** mixing reactive and template-driven form for the same control.
Expand All @@ -26,6 +36,23 @@ sidebar_position: 4
</form>
```

## Signal forms

**Consider** not using signal forms, yet.

:::info Why?
Signal forms are experimental features in Angular v21 and are not recommended for production use as they may change in future releases.
Use [Reactive forms](#reactive-forms) or [Template-driven forms](#template-driven-forms) instead.
:::

## Template-driven forms

**Consider** using template-driven forms for simple interactive components.
- ❌ Multi-field form with validation
- ✅ Toggle button to open/close a menu
- ✅ Simple search bar
- ✅ Single-field form

## Reactive forms

**Consider** using reactive forms for complex forms.
Expand Down Expand Up @@ -54,14 +81,6 @@ Using strings prevents type checking and can cause runtime errors if the control

**Do** use `getRawValue()` to get all control values including disabled controls.

## Template-driven forms

**Consider** using template-driven forms for simple interactive components.
- ❌ Multi-field form with validation
- ✅ Toggle button to open/close a menu
- ✅ Simple search bar
- ✅ Single-field form

## Custom fields

**Do** use `ControlValueAccessor` to create custom form fields.
Expand Down
4 changes: 2 additions & 2 deletions docs/general/code-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_position: 1

This page covers best practices and common mistakes when writing TypeScript code, focusing on those with the highest impact. It includes naming conventions, code clarity, consistency and more.

The following guidelines are a complement to the [Angular official coding style guide](https://angular.dev/style-guide) that we recommend to read first.
The following guidelines are a complement to the [Angular official coding style guide](https://v21.angular.dev/style-guide) that we recommend to read first.

## General guidelines

Expand Down Expand Up @@ -57,7 +57,7 @@ The following guidelines are a complement to the [Angular official coding style
:::warning Exceptions
Avoid using `#` if you're targeting browsers that don't natively support them, as the downleveling can impact performance and bundle size.

You're not concerned if you use [Angular's default browserlist](https://angular.dev/reference/versions#browser-support).
You're not concerned if you use [Angular's default browserlist](https://v21.angular.dev/reference/versions#browser-support).
:::

**Do** use plural form in names for iterables (array, set, ...).
Expand Down
6 changes: 3 additions & 3 deletions docs/general/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Standalone components are self-contained which is much easier to manage, and rem
:::

:::tip
You can run the [schematic migration](https://angular.dev/reference/migrations/standalone) to automatically convert your project to standalone.
You can run the [schematic migration](https://v21.angular.dev/reference/migrations/standalone) to automatically convert your project to standalone.
:::

**Consider** using [Zoneless](https://angular.dev/guide/zoneless).
**Consider** using [Zoneless](https://v21.angular.dev/guide/zoneless).

:::info Why?
Opting for Zoneless mode is a future-proof choice as Angular is moving towards this direction. While the performance impact is minimal (especially if you have already followed best practices, e.g. [`OnPush` change detection](../component/typescript-class#change-detection)), it can improve developer experience by providing clearer stack traces. Additionally, it'll help reduce bundle size and startup time.
Expand Down Expand Up @@ -116,7 +116,7 @@ Committing run configurations ensures that all team members have access to the s
For example, running `npm run build` will first run the `prebuild` script, then `build`, and finally `postbuild`.
:::

**Do** use the [`application` builder](https://angular.dev/tools/cli/build-system-migration).
**Do** use the [`application` builder](https://v21.angular.dev/tools/cli/build-system-migration).
```json title="✅ angular.json"
{
"projects": {
Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ This guide will give you thoughtful opinions on Angular's features, you may not

## Angular version

This documentation assumes that you are using the latest minor version of **Angular v20**.
This documentation assumes that you are using the latest minor version of **Angular v21**.

:::note
Angular Tips follows the same major versioning as Angular itself, starting with v19.

If you're using an older version of Angular, we recommend you read Angular Tips v19. While many of the recommendations remain relevant, some may not be applicable to your specific version. Refer to the official [changelog](https://github.com/angular/angular/releases), [update guide](https://angular.dev/update-guide) and [API reference](https://angular.dev/api) to identify unstable and missing features.
If you're using an older version of Angular, we recommend you read Angular Tips v19. While many of the recommendations remain relevant, some may not be applicable to your specific version. Refer to the official [changelog](https://github.com/angular/angular/releases), [update guide](https://v21.angular.dev/update-guide) and [API reference](https://v21.angular.dev/api) to identify unstable and missing features.
:::

## Vocabulary
Expand Down
2 changes: 1 addition & 1 deletion docs/i18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Angular will use `LOCALE_ID` by default for everything related to internationali

**Consider** using one of the following:

✅ **[Angular built-in i18n](https://angular.dev/guide/i18n)**: compile-time internationalization library that is part of Angular.
✅ **[Angular built-in i18n](https://v21.angular.dev/guide/i18n)**: compile-time internationalization library that is part of Angular.

- ❌ Does not support runtime language switching (needs window refresh)

Expand Down
6 changes: 5 additions & 1 deletion docs/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ sidebar_position: 0
- show app version in UI:
- do NOT import package.json to display version
- use postversion script
- maintenance : use migration guide and schematics
- migration :
- "What's new?" section for each major release?
- angular devtools chrome extension
- testing
- when to test and when not to test
Expand Down Expand Up @@ -71,3 +72,6 @@ sidebar_position: 0
- debugging
- angular chrome devtools
- json pipe
- v21
- zoneless

4 changes: 2 additions & 2 deletions docs/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ It is only once the Angular application has been fully initialized that it can m
}
```

More about deferred loading in the [Angular documentation](https://angular.dev/guide/templates/defer).
More about deferred loading in the [Angular documentation](https://v21.angular.dev/guide/templates/defer).

:::tip
Useful for "below the fold"
Expand All @@ -110,7 +110,7 @@ Might have some exceptions?
}
```

More about incremental hydration in the [Angular documentation](https://angular.dev/guide/incremental-hydration).
More about incremental hydration in the [Angular documentation](https://v21.angular.dev/guide/incremental-hydration).

:::tip
Useful for "above the fold"
Expand Down
6 changes: 3 additions & 3 deletions docs/reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ nbDevelopersInTeam = computed(() => this.teamDevelopers().length);

### Writable and derived state

**Do** use [`linkedSignal()`](https://angular.dev/guide/signals/linked-signal) for writable state that depends on another signal.
**Do** use [`linkedSignal()`](https://v21.angular.dev/guide/signals/linked-signal) for writable state that depends on another signal.

```ts title="✅ Selecting an item from a reactive array"
// Reactive array of users (could also be a computed(), input() or other).
Expand Down Expand Up @@ -133,10 +133,10 @@ constructor() {

### Fetching data

**Consider** not using `resource()`, `rxResource()` or `httpResource()` signals.
**Consider** not using `resource()`, `rxResource()` or `httpResource()` signals, yet.

:::info Why?
`resource()`, `rxResource()` and `httpResource()` are experimental features in Angular v20 and are not recommended for production use.
`resource()`, `rxResource()` and `httpResource()` are experimental features in Angular v21 and are not recommended for production use as they may change in future releases.
:::

:::warning Exceptions
Expand Down
59 changes: 23 additions & 36 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,42 @@ sidebar_position: 10

Testing is a crucial part of software development, especially for large applications, as it improves reliability and maintainability.

:::warning
The Angular testing ecosystem is currently in a transitioning state. Officialy supported tools are deprecated, and the community is actively exploring modern alternatives. Expect recommendations and best practices to evolve in the near future as the ecosystem stabilizes.
:::

## Testing frameworks

**Do** use a testing framework.

✅ **[Karma](https://karma-runner.github.io/)** is the pre-installed test runner with [Jasmine](https://jasmine.github.io/) as the assertion library.

- ✅ Officially supported by Angular
- ✅ Real browser testing
- ❌ Deprecated and no longer maintained
- ❌ Slow
- ❌ Angular support will probably drop in future releases
- ✅ [Vitest](https://vitest.dev/)

:::info Why?
Even if Karma is deprecated, it is still a valid option as it's the only officially supported framework, and it gets the job done. Other options may or may not be supported in the future, they are currently not as well integrated with Angular and may require additional configuration to work.
:::

✅ **[Vitest](https://vitest.dev/)**

- ✅ Fast
- ✅ Simulated and real browser testing
- ❌ Experimental Angular support

✅ **[Jest](https://jestjs.io/)**
The Angular testing ecosystem has completed its transition. Karma and Jasmine have been replaced by Vitest as the recommended and default testing framework in Angular v21. While legacy projects may still use Karma/Jasmine, new projects should adopt Vitest for better performance and modern tooling.

- ✅ Fast
- ❌ Experimental Angular support
- ❌ No real browser testing

✅ **[Web Test Runner](https://modern-web.dev/docs/test-runner/overview/)**
Vitest offers a fast and efficient testing experience with support for both simulated and real browser environments. It is actively maintained, officially supported by Angular and integrated directly into the Angular CLI.
:::

- ✅ Real browser testing
- ❌ Experimental Angular support
- ❌ [Karma](https://karma-runner.github.io/) and [Jasmine](https://jasmine.github.io/)

## End-to-end testing tools (e2e)
:::info Why?
Karma has been the default test runner for Angular applications for many years. However, it has been deprecated in 2023 and is no longer maintained. Vitest replaced it as the default testing framework in Angular in v21, and Angular's support for Karma/Jasmine will drop in future releases.

**Do** use one of the following:
You can still use Karma and Jasmine for existing projects, but you will most likely need to migrate to Vitest in the future to ensure compatibility with newer Angular versions. For new projects, you should directly start with Vitest.
:::

✅ **[Playwright](https://playwright.dev/)**
- ❌ [Jest](https://jestjs.io/)
- ❌ [Web Test Runner](https://modern-web.dev/docs/test-runner/overview/)

✅ **[Cypress](https://docs.cypress.io/)**
:::info Why?
Jest and Web Test Runner were evaluated as potential alternatives to Karma/Jasmine but were not chosen as the official recommendation. Experimental support for Jest and Web Test Runner is deprecated and will be removed in Angular v22.
:::

✅ **[Puppeteer](https://pptr.dev/)**
## End-to-end testing (e2e)

✅ **[WebdriverIO](https://webdriver.io/)**
**Consider** e2e testing for critical user flows and complex interactions.

✅ **[Nightwatch.js](https://nightwatchjs.org/)**
**Do** use an e2e testing tool.

❌ **[Protractor](https://www.protractortest.org/)**: deprecated and no longer maintained.
- ✅ [Playwright](https://playwright.dev/)
- ✅ [Cypress](https://docs.cypress.io/)
- ✅ [Puppeteer](https://pptr.dev/)
- ✅ [WebdriverIO](https://webdriver.io/)
- ✅ [Nightwatch.js](https://nightwatchjs.org/)
- ❌ [Protractor](https://www.protractortest.org/): deprecated and no longer maintained.
4 changes: 2 additions & 2 deletions docs/ui-libraries/angular-material.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ CSS classes, HTML structure and private CSS variables are Material's internal im
}
```

**Do** override CSS [system variables](https://material.angular.dev/guide/system-variables).
**Do** override CSS [system variables](https://v21.material.angular.dev/guide/system-variables).
```css title="✅ System variables"
@include mat.theme-overrides((
primary-container: green
Expand All @@ -51,7 +51,7 @@ Angular Material provides public and stable APIs to customize the look of compon

## Custom components

**Consider** using [Angular CDK](https://material.angular.dev/cdk).
**Consider** using [Angular CDK](https://v21.material.angular.dev/cdk).
- ❌ Work around the limitations of Angular Material's components
- ✅ Build custom components with CDK utilities

Expand Down
4 changes: 2 additions & 2 deletions docs/ui-libraries/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Headless UI libraries are not so popular and advanced in the Angular ecosystem c

**Consider** using one of the following:

✅ **[Angular Material](https://material.angular.dev/)**: the official Angular component library that implements Material Design. It provides essential UI components and is well-maintained by the Angular team.
✅ **[Angular Material](https://v21.material.angular.dev/)**: the official Angular component library that implements Material Design. It provides essential UI components and is well-maintained by the Angular team.

- ✅ High quality components
- ✅ Always up to date with Angular releases
Expand Down Expand Up @@ -47,7 +47,7 @@ Headless UI libraries are not so popular and advanced in the Angular ecosystem c

**Consider** using the following:

✅ **[Angular CDK](https://material.angular.dev/cdk)**:
✅ **[Angular CDK](https://v21.material.angular.dev/cdk)**:
The Component Development Kit (CDK) is a set of low-level primitives for building UI components, such as overlays, drag-and-drop, and accessibility features.

- ✅ High quality primitives
Expand Down
Loading