fbpx Skip to content

Aquent | DEV6

Manual Bootstrap for Angular Applications

Written by: Alex Krasavtsev

Angular is one of the best frameworks for a single page application. However, when it comes to a regular website, server-rendered content may be a preferred choice for many reasons. SEO is the biggest concern.

What would you say about mixing server-rendered content with an Angular application? This would enable you to utilize Angular on your website while maintaining good SEO practices. It would be the best of both worlds. Let’s say, the primary content is rendered by a server and different Angular widgets are scattered across different parts of a page or pages enriching user experience. You can utilize Angular for site search, user login/logout, commenting, etc., enabling users to perform an intended action without leaving a page.

Here is how you can implement such a solution:

  1. Implement functionality within your custom modules (e.g. search, authorization, comments)
  2. Import these modules inside the root module
  3. Import components for these modules
  4. Bootstrap required components
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
  
import { SearchModule } from './search/search.module';
import { AuthorizationModule } from './authorization/authorization.module';
import { CommentsModule } from './comments/comments.module';
  
import { SearchComponent} from './search/search.component';
import { AuthorizationComponent } from './authorization/authorization.component';
import { CommentsComponent } from './comments/comments.component';
  
@NgModule({
  imports: [
    SearchModule,
    AuthorizationModule,
    CommentsModule
  ],
  providers: [],
  bootstrap: [
    SearchComponent,
    AuthorizationComponent,
    CommentsComponent
  ]
})
  
export class AppModule {}
  
///  HTML
  
<div>Server rendered content 1</div>
<site-search></site-search>
  
<div>Server rendered content 2</div>
<authorization</authorization>
  
<div>Server rendered content 3</div>
<comments></comments>

There is one problem with such an approach. If a component is not present on any given page, Angular will trigger an error. To overcome this issue, you could develop several apps and load different combinations of them on different pages. However, as you can imagine code maintenance will be an issue and you will have to figure out on the server-side which application(s) to load. Also, data exchange between those apps will be a problem.

Thankfully, there is a better approach. You can utilize manual bootstrap. We previously explained how you can manually bootstrap AngularJS applications in this blog post (https://www.dev6.com/angular-deferred-bootstrap). Here is how you can do manual bootstrap with an Angular app.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ApplicationRef } from '@angular/core';
  
import { SearchModule } from './search/search.module';
import { AuthorizationModule } from './authorization/authorization.module';
import { CommentsModule } from './comments/comments.module';
  
import { SearchComponent} from './search/search.component';
import { AuthorizationComponent } from './authorization/authorization.component';
import { CommentsComponent } from './comments/comments.component';
  
@NgModule({
  imports: [
    SearchModule,
    AuthorizationModule,
    CommentsModule
  ],
  providers: [],
  entryComponents: [
    SearchComponent,
    AuthorizationComponent,
    CommentsComponent
  ]
})
  
export class AppModule {
  ngDoBootstrap(app: ApplicationRef) {
  
    app.bootstrap(SearchComponent);
    app.bootstrap(AuthorizationComponent);
  
    if (document.getElementsByTagName("comments").length > 0) {
      app.bootstrap(CommentsComponent);
    }
  }
}
  
///  HTML
  
///  Page 1
  
<div>Server rendered content 1</div>
<site-search></site-search>
  
<div>Server rendered content 2</div>
<authorization</authorization>
  
/// Page 2
  
<div>Server rendered content 1</div>
<site-search></site-search>
  
<div>Server rendered content 2</div>
<authorization</authorization>
  
<div>Server rendered content 3</div>
<comments></comments>

Here is the list of changes:

  1. Import the ApplicationRef interface
  2. Implement ngDoBootstrap method, which has only one parameter – a reference to the application.
  3. Inside NgModule decorator use entryComponents array, instead of the bootstrap one.  Angular will create components factories, which you can utilize inside the ngDoBootstrapmethod.
  4. Then, inside the ngDoBootstrap method use app.bootstrap(componentName) to bootstrap components which are present on every page
  5. Do a conditional bootstrap for components which are not present on every page, like the comments component in my example.

Voilà, you just enriched your server-rendered pages with multiple angular modules.

I hope you find this example of manual bootstrap useful. Please, do not hesitate to let us know about other possible uses of manual bootstrap for Angular applications. 

Sign up for our Angular Course

$1,995 CAD – 4 Days

View Course Details