Angular v16 has been released with a new set of APIs for Angular Universal. This guide will help you migrate your existing Angular Universal application to use the new APIs. Angular provides a set of…
Published May 5, 2023

Migrate Angular Universal to use Standalone APIs

Angular v16 has been released with a new set of APIs for Angular Universal. This guide will help you migrate your existing Angular Universal application to use the new APIs.

There are two main steps to migrate your application to use the new APIs:

  • Migrate your application to use standalone APIs
  • Migrate your server to use the new APIs

Migrate your application to use standalone APIs

Angular provides a set of schematics to help you migrate your application to use the new APIs. To run the schematics, run the following command:

ng generate @angular/core:standalone

I don’t want to deep dive a lot here as it’s covered in the docs. You can read more about the migration in the Angular Standalone Migration.

In order to have an easy to follow guide, we will make sure we have the same structure as the one that gets generated by default when you create a new Angular application.

First, we have to make sure that we use bootstrapApplication in main.ts.

Second, we have to move the providers from main.ts to an app.config.ts file. The app.config.ts file may look like this:

import { TitleStrategy, provideRouter } from '@angular/router';
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

import { CustomTitleStrategy } from './custom-title-strategy';
import { routes } from './routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(),
    { provide: TitleStrategy, useClass: CustomTitleStrategy },
  ],
};

Our main.ts file will look like this:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

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

Now, let’s create another file for our server configuration. We will call it app.config.server.ts and it will look like this:

import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
import { appConfig } from './app.config';

const serverConfig: ApplicationConfig = {
  providers: [provideServerRendering()],
};

export const config = mergeApplicationConfig(appConfig, serverConfig);

As you can see, we are using mergeApplicationConfig to merge the two configurations. We are also adding provideServerRendering to the server configuration to enable server rendering. This configuration will replace the AppServerModule class.

We will use this configuration later when we migrate our server.

Now, we need to update our main.server.ts file to use the new APIs. It will look like this:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { config } from './app/app.config.server';

const bootstrap = () => bootstrapApplication(AppComponent, config);

export default bootstrap;

So, we are using bootstrapApplication to bootstrap our application and we are passing the config we created earlier with the server configurations. We are also exporting a function called bootstrap that we will use later in our server.

Migrate your server to use the new APIs

As a last step, we need to update our server.ts file to use the new file we created.

// import bootstrap that we exported from main.server.ts and remove AppServerModule import
- import { AppServerModule } from './src/main.server';
+ import bootstrap from './src/main.server';

export function app(): express.Express {
  const server = express();
  // other code here

// Replace AppServerModule with bootstrap function
-  server.engine('html', ngExpressEngine({ bootstrap: AppServerModule }));
+  server.engine('html', ngExpressEngine({ bootstrap }));

  return server;
}

+export default bootstrap;

Finally, we have migrated our application to use the new APIs 🎉.

NOTES:

  • If you are using the TransferHttpCacheModule, just remove it because it’s provided by default now.

Lately I migrated one of my projects to use this new api-s, so here’s the commit with the changes: https://github.com/eneajaho/ngx-isr/commit/cee0c64282c2e8965397c2de959ea82b7b9a39ac

Thanks for reading!

If this article was interesting and useful to you, and you want to learn more about Angular, support me by buying me a coffee ☕️ or follow me on X (formerly Twitter) @Enea_Jahollari where I tweet and blog a lot about Angular latest news, signals, videos, podcasts, updates, RFCs, pull requests and so much more. 💎


Share this article:

Previous articles

Don't miss out on our previous articles.