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
7 changes: 7 additions & 0 deletions docs/standalone-apis/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Standalone APIs",
"link": {
"type": "generated-index",
"description": "Guides for using Angular's Standalone APIs, including Standalone Components."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Adding top-level routes to a standalone Angular application

## Interoperability using the RouterModule

As of Angular version 14.0.0-rc.0, there is no dedicated standalone API for the Angular router so we pass `RouterModule.forRoot` to the `importProvidersFrom` function:

```typescript
import { enableProdMode, importProvidersFrom } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";
import { RouterModule, Routes } from "@angular/router";

import { AboutComponent } from "./app/about.component";
import { AppComponent } from "./app/app.component";
import { HomeComponent } from "./app/home.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

const routes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "home",
},
{
path: "home",
component: HomeComponent,
},
{
path: "about",
component: AboutComponent,
},
];

bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(RouterModule.forRoot(routes))],
}).catch((err) => console.error(err));
```

## Future standalone API

In a future Angular version, a function creating the necessary providers will be available. It might look something like this:

```typescript
import { enableProdMode } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";
import { Routes, withRoutes } from "@angular/router";

import { AboutComponent } from "./app/about.component";
import { AppComponent } from "./app/app.component";
import { HomeComponent } from "./app/home.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

const routes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "home",
},
{
path: "home",
component: HomeComponent,
},
{
path: "about",
component: AboutComponent,
},
];

bootstrapApplication(AppComponent, {
providers: [withRoutes(routes)],
}).catch((err) => console.error(err));
```
66 changes: 66 additions & 0 deletions docs/standalone-apis/bootstrapping-a-standalone-application.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Bootstrapping a standalone application

## Using the bootstrapApplication function

A standalone Angular application bootstraps a component often called the `AppComponent`, making it the root component of our application. We use the `bootstrapApplication` function to do this. It accepts the class of the root component as its first parameter and optionally an object with a `providers` property that contains an array of application-wide providers.

The following code block lists a simple `main.ts` file:

<!-- TODO(LayZeeDK): support code highlighting -->

```typescript
import { enableProdMode } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";

import { AppComponent } from "./app/app.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

bootstrapApplication(AppComponent).catch((err) => console.error(err));
```

## Application-wide providers

To add a root-level provider, we can add it to the `providers` array:

```typescript
import { enableProdMode } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";

import { AppComponent } from "./app/app.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

bootstrapApplication(AppComponent, {
providers: [AuthService],
}).catch((err) => console.error(err));
```

## Using providers from NgModules

To provide root-level providers using an NgModule, we pass the NgModule to the `importProvidersFrom` function.

For example, we can provide the `HttpClient`'s dependencies as shown in the following listing:

```typescript
import { HttpClientModule } from "@angular/common/http";
import { enableProdMode, importProvidersFrom } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";

import { AppComponent } from "./app/app.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(HttpClientModule)],
}).catch((err) => console.error(err));
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Enabling animations in a standalone Angular application

## Interoperability using the BrowserAnimationsModule

As of Angular version 14.0.0-rc.0, there is no dedicated standalone API for Angular browser animations so we pass `BrowserAnimationsModule` to the `importProvidersFrom` function:

```typescript
import { enableProdMode, importProvidersFrom } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";

import { AppComponent } from "./app/app.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

bootstrapApplication(AppComponent, {
providers: [importProvidersFrom(BrowserAnimationsModule)],
}).catch((err) => console.error(err));
```

## Future standalone API

In a future Angular version, a function creating the necessary providers will be available. It might look something like this:

```typescript
import { enableProdMode } from "@angular/core";
import { bootstrapApplication } from "@angular/platform-browser";
import { withAnimations } from "@angular/platform-browser/animations";

import { AppComponent } from "./app/app.component";
import { environment } from "./environments/environment";

if (environment.production) {
enableProdMode();
}

bootstrapApplication(AppComponent, {
providers: [withAnimations()],
}).catch((err) => console.error(err));
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Lazy loading a feature using the Angular Router

## Resolving a Routes array

To lazy load an Angular feature, resolve a `Routes` array from the dynamic `import` statement returned by a `loadChildren` callback:

```typescript
import { Routes } from "@angular/router";

import { AboutComponent } from "./app/about.component";
import { HomeComponent } from "./app/home.component";

export const routes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "home",
},
{
path: "home",
component: HomeComponent,
},
{
path: "about",
component: AboutComponent,
},
{
path: "category",
loadChildren: () => import("./category/category.routes").then((m) => m.routes),
},
];
```

## Exporting feature routes

Our Angular feature exports a `Routes` array to enable lazy loading using the Angular Router.

```typescript
import { Routes } from "@angular/router";

import { CategoryComponent } from "./category.component";
import { CategoryListComponent } from "./category-list.component";

export const routes: Routes = [
{
path: "",
pathMatch: "full",
component: CategoryListComponent,
},
{
path: ":name",
component: CategoryComponent,
},
];
```

## Lazy loading specific components in a feature

Let's say that we wanted to eagerly load the default component of our feature, in this case the `CategoryListComponent`. Our routes configuration is the same as in the previous section. Now let's say that we wanted to lazy load the `CategoryComponent` used to display individual categories. We do this by adding a `loadComponent` callback to the component route:

```typescript
import { Routes } from "@angular/router";

import { CategoryListComponent } from "./category-list.component";

export const routes: Routes = [
{
path: "",
pathMatch: "full",
component: CategoryListComponent,
},
{
path: ":name",
loadComponent: () => import("./category.component").then((m) => m.CategoryComponent),
},
];
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Lazy loading a standalone component using the Angular Router

Add a `loadComponent` property to a `Route` object to lazy load a component. The value is a function that returns a dynamic `import` statement that points to an ES module (a `.ts` file), then resolves to the component class:

```typescript
import { Routes } from "@angular/router";

import { HomeComponent } from "./app/home.component";

export const routes: Routes = [
{
path: "",
pathMatch: "full",
redirectTo: "home",
},
{
path: "home",
component: HomeComponent,
},
{
path: "about",
loadComponent: () => import("./about.component").then((m) => m.AboutComponent),
},
];
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Providing dependencies in a standalone Angular feature

## Using route providers

If all routes in a feature `Routes` array are top-level routes, we can wrap them in a component-less route with an empty path by nesting them in an array assigned to its `children` property.

Next, we add the feature-specific dependencies to the `providers` array of our feature routes:

```typescript
import { Routes } from "@angular/router";

import { CategoryComponent } from "./category.component";
import { CategoryHttpClient } from "./category-http-client.service";
import { CategoryListComponent } from "./category-list.component";
import { CategoryState } from "./category-state.service";

export const routes: Routes = [
{
path: "",
children: [
{
path: "",
pathMatch: "full",
component: CategoryListComponent,
},
{
path: ":name",
component: CategoryComponent,
},
],
providers: [CategoryHttpClient, CategoryState],
},
];
```

## Interoperability with NgModules

Angular libraries using the forRoot-forFeature pattern expose an NgModule that provides dependencies that we must load with the Angular feature using it. To use it in a standalone Angular feature, we pass the NgModule to the `importProvidersFrom` function:

```typescript
import { importProvidersFrom } from "@angular/core";
import { Routes } from "@angular/router";
import { EffectsModule } from "@ngrx/effects";
import { StoreModule } from "@ngrx/store";

import { CategoryEffects } from "./+state/effects";
import { categoryFeature } from "./+state/reducers";
import { CategoryComponent } from "./category.component";
import { CategoryListComponent } from "./category-list.component";

export const routes: Routes = [
{
path: "",
children: [
{
path: "",
pathMatch: "full",
component: CategoryListComponent,
},
{
path: ":name",
component: CategoryComponent,
},
],
providers: [
importProvidersFrom(EffectsModule.forFeature([CategoryEffects])),
importProvidersFrom(StoreModule.forFeature(categoryFeature)),
],
},
];
```
Loading