In this guide, I will walk you through setting up API routes in a server-side rendered Angular 18 application, leveraging Express to create RESTful endpoints.
Prerequisites
You’ll need the following:
- Node.j 20 or later
Table Of Contents
- Create a new Angular Application
- Adding an API Route in server.ts
- Configuring app.config.ts for HttpClient
- Fetching Data in app.component.ts
- Running the Server in SSR Mode
Create a new Angular Application
Let’s get started by creating a new Angular project. Execute the following commands:
npm install -g @angular/cli@latestng new angular-ssr-api-routesng new is the recommended way to scaffold an Angular project quickly.
When prompted, choose:
CSSfor the stylesheet formatyfor enabling Server-Side Rendering (SSR) and Static Site Generation (SSR/Prerendering)
Once that is done, move into the project directory and start the app in development mode by executing the following command:
cd angular-ssr-api-routesnpm run startThe app should be running on localhost:4200.
In angular.json, set "prerender": false to ensure the application only uses server-side rendering without prerendering.
Adding an API Route in server.ts
Next, define an API route in server.ts to serve data for your SSR application. Open server.ts and add the following code:
// ...
// Example Express Rest API endpoints// server.get('/api/**', (req, res) => { });// Serve static files from /browserserver.get('**', express.static(browserDistFolder, { maxAge: '1y', index: 'index.html',}));
server.get('/api/data', (req, res) => { res.json({ code: 1 });})
// ...This route (/api/data) will return a JSON response { code: 1 }, which can be fetched by the Angular application.
Configuring app.config.ts for HttpClient
In order to fetch data from our new API endpoint, make sure HttpClient is set up using fetch. Open app.config.ts and add provideHttpClient:
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { provideRouter } from '@angular/router';
import { routes } from './app.routes';import { provideClientHydration } from '@angular/platform-browser';import { provideHttpClient, withFetch } from '@angular/common/http';
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideClientHydration(), provideHttpClient(withFetch()), ],};Fetching Data in app.component.ts
To retrieve data from the API route on the client side, open app.component.ts and set up a simple data-fetching function that runs on component initialization:
import { isPlatformBrowser } from '@angular/common';import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core';import { RouterOutlet } from '@angular/router';
@Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css',})export class AppComponent implements OnInit { isBrowser: boolean; title = 'with-angular'; constructor(@Inject(PLATFORM_ID) platformId: Object) { this.isBrowser = isPlatformBrowser(platformId); } async ngOnInit() { if (this.isBrowser) { const fetchCall = await fetch('/api/data'); const fetchResp = await fetchCall.json(); // Do something } }}In this setup:
isPlatformBrowseris used to ensure the API call only happens on the client side, not on the server side.- The component fetches data from the
/api/dataendpoint upon initialization and logs it to the console.
Running the Server in SSR Mode
To test your API routes in server-side rendering mode, you need to build and serve the Angular application:
In one terminal:
npm run watchIn a separate terminal, run:
npm run serve:ssr:angular-ssr-api-routesYour application, now with server-side rendering and API routing, should be accessible at localhost:4200.
Conclusion
In this guide, we covered how to set up API routes for server-side rendering in an Angular 18 application. Using this approach, you can serve data dynamically from the server and enhance your application’s performance with server-rendered content.
If you have any questions or comments, feel free to reach out to me on Twitter.