Angular applications traditionally render content directly in the user’s browser, which can sometimes lead to challenges with search engine optimization (SEO) and initial page load performance. Server-Side Rendering (SSR) offers a robust solution, allowing Angular applications to render on the server before being sent to the client. This guide will walk you through enabling SSR in your Angular project, highlighting its benefits and demonstrating a practical use case.
Why Embrace Server-Side Rendering?
Integrating SSR into your Angular application brings several significant advantages:
- Enhanced SEO: Search engines can more effectively crawl and index your dynamic content, leading to better visibility.
- Improved Performance: Achieve faster “first-paint” and “Time-to-Interactive (TTI),” providing a snappier user experience.
- Custom HTTP Status Codes: Gain the ability to send specific HTTP status codes (e.g., 404 Not Found) directly from the server, crucial for proper error handling.
- CMS Preview Rendering: Facilitate better previewing of content for content management system (CMS) editors.
Scenario: Gracefully Handling 404 Not Found Pages with SSR
Consider an Angular application where certain pages might not exist. Without SSR, an Angular app running in the browser cannot dictate the HTTP status code sent by the server. This means a “page not found” scenario might still return a 200 OK status, confusing search engines and users.
With SSR, we can inject the server’s response object directly into our Angular application. This allows us to programmatically set custom HTTP status codes, such as a proper 404 (Not Found) when a requested resource is unavailable.
Tools of the Trade: @nguniversal/express-engine
Our SSR implementation leverages @nguniversal/express-engine, an Express.js-based adapter that enables rendering Angular components on the server.
Step-by-Step SSR Setup
Follow these steps to integrate Angular Universal (SSR) into your project:
1. Add Angular Universal to Your Project:
Open your terminal in your Angular project directory and run the following command:
ng add @nguniversal/express-engine
2. Verify Project File Structure:
After executing the command, confirm that your project now includes these essential files and updates:
server.ts
main.ts
main.server.ts
- Your
angular.json
file should be updated with a new server target configuration.
3. Configure Key Files for SSR:
Minor adjustments are often needed in generated files to ensure optimal SSR functionality, especially for client-side routing and response handling.
server.ts
: This file serves as your Express server. Ensure it correctly renders your Angular application and handles static assets. Crucially, it should include a provider for theRESPONSE
token to allow Angular components to interact with the server’s response object.
Key Snippet forserver.ts
(focus onproviders
):import { RESPONSE } from '@nguniversal/express-engine/tokens'; // ... other imports and setup ... commonEngine .render({ // ... providers: [ // ... { provide: RESPONSE, useValue: res } // 'res' is the Express response object ], }) // ...
main.ts
: This file typically remains largely unchanged, bootstrapping your client-side Angular application.main.server.ts
: This file exports yourAppServerModule
, which is the entry point for your server-side Angular application.export { AppServerModule as default } from './app/app.module.server';
Running Your SSR-Enabled Application
To run your Angular application with SSR, you’ll typically use a script defined in your package.json
.
- Check/Add Server Script in
package.json
:
Look for a script similar to this; if missing, add it (remember to replace placeholders with your actual project name):"scripts": { // ... other scripts "serve:ssr:YOUR_PROJECT_NAME": "node dist/your-project-name/server/server.mjs" }
- Execute the SSR Command:
Run the following command in your terminal (again, replaceYOUR_PROJECT_NAME
):npm run serve:ssr:YOUR_PROJECT_NAME
Practical Application: Implementing a 404 Page with SSR
Let’s put SSR to work by creating a dedicated 404 “Page Not Found” experience that correctly signals its status to the server.
1. Develop a Specific 404 Component:
Create an Angular component (e.g., NotFoundPageComponent
) that will be displayed when a 404 error occurs.
2. Utilize the RESPONSE
Token:
Within your NotFoundPageComponent
(or any component needing to set a custom status code), inject the RESPONSE
token. This token provides access to the server’s HTTP response object during SSR.
import { Component, OnInit, Optional, Inject } from '@angular/core';
import { RESPONSE } from '@nguniversal/express-engine/tokens';
import { Router } from '@angular/router'; // Assuming you might use Router for redirects or further logic
@Component({
selector: 'app-not-found',
template: `
<h1>404 - Page Not Found</h1>
<p>The page you are looking for does not exist.</p>
<a routerLink="/">Go to Home</a>
`,
styleUrls: ['./not-found.component.css']
})
export class NotFoundPageComponent implements OnInit {
constructor(
private router: Router,
@Optional() @Inject(RESPONSE) private response: any // Inject the server response
) {}
ngOnInit(): void {
// Only attempt to set status code during SSR
if (this.response) {
this.response.statusCode = 404;
this.response.statusMessage = 'Page Not Found';
}
}
}
By including the @Optional() @Inject(RESPONSE)
decorator, your component can safely access the response object only when running in a server-side environment. This ensures your application functions correctly in both browser and server contexts.
3. Routing and Detection:
You would configure your routing to direct to this component on a 404. If you have a content management system (CMS) or a Backend for Frontend (BFF) architecture, your server-side logic can detect a 404 from the backend and then render this specific Angular component, correctly setting the status code.
Concluding Thoughts
Implementing Server-Side Rendering with Angular Universal provides a powerful way to significantly boost your application’s SEO, initial loading performance, and overall robustness. By following these steps, you can create modern, CMS-driven, and search engine-friendly Angular applications that deliver an excellent user experience from the very first paint. Embrace SSR to unlock the full potential of your Angular projects!