diff --git a/docs/standalone-apis/_category_.json b/docs/standalone-apis/_category_.json new file mode 100644 index 0000000..072966b --- /dev/null +++ b/docs/standalone-apis/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Standalone APIs", + "link": { + "type": "generated-index", + "description": "Guides for using Angular's Standalone APIs, including Standalone Components." + } +} diff --git a/docs/standalone-apis/adding-top-level-routes-to-a-standalone-angular-application.md b/docs/standalone-apis/adding-top-level-routes-to-a-standalone-angular-application.md new file mode 100644 index 0000000..75ca071 --- /dev/null +++ b/docs/standalone-apis/adding-top-level-routes-to-a-standalone-angular-application.md @@ -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)); +``` diff --git a/docs/standalone-apis/bootstrapping-a-standalone-application.md b/docs/standalone-apis/bootstrapping-a-standalone-application.md new file mode 100644 index 0000000..26bc697 --- /dev/null +++ b/docs/standalone-apis/bootstrapping-a-standalone-application.md @@ -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: + + + +```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)); +``` diff --git a/docs/standalone-apis/enabling-animations-in-a-standalone-angular-application.md b/docs/standalone-apis/enabling-animations-in-a-standalone-angular-application.md new file mode 100644 index 0000000..18062a5 --- /dev/null +++ b/docs/standalone-apis/enabling-animations-in-a-standalone-angular-application.md @@ -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)); +``` diff --git a/docs/standalone-apis/lazy-loading-a-feature-using-the-angular-router.md b/docs/standalone-apis/lazy-loading-a-feature-using-the-angular-router.md new file mode 100644 index 0000000..b50e375 --- /dev/null +++ b/docs/standalone-apis/lazy-loading-a-feature-using-the-angular-router.md @@ -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), + }, +]; +``` diff --git a/docs/standalone-apis/lazy-loading-a-standalone-component-using-the-angular-router.md b/docs/standalone-apis/lazy-loading-a-standalone-component-using-the-angular-router.md new file mode 100644 index 0000000..25097c7 --- /dev/null +++ b/docs/standalone-apis/lazy-loading-a-standalone-component-using-the-angular-router.md @@ -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), + }, +]; +``` diff --git a/docs/standalone-apis/providing-dependencies-in-a-standalone-angular-feature.md b/docs/standalone-apis/providing-dependencies-in-a-standalone-angular-feature.md new file mode 100644 index 0000000..188885e --- /dev/null +++ b/docs/standalone-apis/providing-dependencies-in-a-standalone-angular-feature.md @@ -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)), + ], + }, +]; +``` diff --git a/docs/standalone-apis/using-the-httpclient-in-a-standalone-angular-application.md b/docs/standalone-apis/using-the-httpclient-in-a-standalone-angular-application.md new file mode 100644 index 0000000..28ebb3b --- /dev/null +++ b/docs/standalone-apis/using-the-httpclient-in-a-standalone-angular-application.md @@ -0,0 +1,46 @@ +# Using the HttpClient in a standalone Angular application + +As you might know, Angular's `HttpClient` has many dependencies that we have to provide in Angular applications using it. + +## Interoperability using the HttpClientModule + +As of Angular version 14.0.0-rc.0, there is no dedicated standalone API for the Angular HTTP client so we pass for example `HttpClientModule` to the `importProvidersFrom` function: + +```typescript +import { HttpClientModule } from "@angular/common/http"; +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(HttpClientModule)], +}).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 { withHttpClient } from "@angular/common/http"; +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: [withHttpClient()], +}).catch((err) => console.error(err)); +``` diff --git a/docusaurus.config.js b/docusaurus.config.js index c70ef28..ef08e21 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -163,6 +163,12 @@ const config = { // position: "left", // type: "doc", // }, + { + docId: "/category/standalone-apis", + label: "Standalone APIs", + position: "left", + type: "doc", + }, // { // docId: "/category/state-management", // label: "State management",