SEO AND ANGULAR
This project will consist of creating a Server Side Rendering (SSR) and how to implement it so that our SPA application with Angular can be detected by the web (SEO) making use of Angular Universal (@nguniversal/express-engine)
If you need help the following explanatory video is available: https://www.youtube.com/watch?v=J8PDfVY2FfI.
Danger of SPA with SEO
The great advantage of SPA applications (client-side applications) is that they work on the client side. For example a website created in the Angular framework runs on the client, that is, in the user's browser and not on a remote server. This type of web application shows all the screens on the same page, without reloading the browser.
The problem arises with Google. When a website is crawled; the robots/crawlers of Google or Yahoo search engines work in a way similar to the curl command. Why? Simple, starting the browser and executing JavaScript is a costly and, therefore, unfeasible task. There is neither time nor resources to do it when it needs to search thousands of pages.
The real example
Create an Angular application and verify how the robots see it: Now, in the other terminal window, run the curl command and take a look at the output: As we can observe, it does not render the website correctly and our web application with Angular has not been detected correctly, that is, the search engines consider that there is no content.
The solution
The solution to this problem is to use @nguniversal/express-engine . With this module we will be able to use Server Side Rendering to render the content on the server and thus serve it complete to the user.
What do we need? For that we need to have installed:
- Node and NPM installed.
- Angular CLI installed
What does Angular Universal offer us?
It is a technology that will allow us to run our Angular application from the server.
It generates static application pages on the server by means of the process called SSR (server side rendering or server-side rendering) that will allow us to cover the dark areas that occur in modern development:
- Facilitate SEO indexing
- Improve application performance on low-power devices
- Show the first page quickly
The importance of implementing SEO in a project
It is a very important part for any business whether small, medium or large. The objective of SEO is to get as many people as possible to visit our website or our company's website and for that a series of procedures and techniques are defined that will allow our website to have a greater repercussion
There are two types:
- SEO on page: it is everything that you can do with respect to the code of our website so that it generates more traffic and it is what we are going to see in this section
- SEO off page: as its name indicates it is everything related to your business outside your page, that is, what corresponds to social networks, advertising, etc.
In order to obtain these objectives, in our Angular application we are going to implement the following solution:
In it we can observe: - The user requests the page.
- The request reaches the server
- NodeJS generates HTML and sends it to the browser
- The browser shows the view from the HTML and immediately shows it to the user, simultaneously JavaScript is being executed
- When JavaScript finishes starting the application, it changes the view represented in HTML with the Angular application
- The user sees a totally interactive Angular application
Well. We know the theory. Let us practice now.
Applying SSR with Angular Universal
That is where @nguniversal/express-engine comes into play. Write a simple command:
ng add @nguniversal/express-engine
We must remember that Angular CLI uses the directive "ng add" from the beginning of the use of schematics to modify our code and adapt it to the new functionality that we want to implement.
If we did the process manually we would have to follow the following steps, which as you can see are many:
- Install new dependencies
- Edit the main.ts file
- Edit the app.module.ts file
- Edit the angular.json file
- Create the file src/app/app.server.module.ts
- Create the file src/main.server.ts
- Create the file server.ts
- Create the file tsconfig.server.json
- Create the file webpack.server.config.js
- Edit the angular.json file
- Edit the package.json file
Now that we already have our application adapted to server-side rendering (SSR), with what we have seen so far, our application will be more than covered in terms of offering the best experience for users while at the same time we will manage to send indexable content for robots... improving this negative point in SPA-type applications.
Launch the application
The following commands are executed to launch the application:
npm run build:ssr
npm run serve:ssr
And if we execute the same statement as before we find the following html code:
curl localhost:4000
What happens with window and localStorage?
NodeJS and browsers can run in 99% of cases with the same code. But there are some things that can only run in NodeJS or only in the browser. Now we will focus on solving these incidents
Window: it is the browser used by the client. A crawler does not use a window then, if for example we want to use the following code it would give us an error:
public ngOnInit (): void {
console.log (window.URL);
}
In my case, for that problem I have applied the following solution:
import {Component, Inject, OnInit, PLATFORM_ID} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
@Component ( {
...
export class xxxxComponent implements OnInit {
isBrowser;
constructor(@Inject(PLATFORM_ID) private platformId: object) {
this.isBrowser = isPlatformBrowser(platformId);
}
ngOnInit() {
if (this.isBrowser) {
if (document.cookie.indexOf(this.cookie_name + '=1') >= 0) {
....
}
}
}
That is to say, with PLATFORM_ID I can check whether or not there is a window requesting the information. In the affirmative case, I generate the necessary code so that the necessary logic is shown, in the negative case, I show the desired logic in that case.
Production deployment
In my case, I have decided to use pm2 to execute the server, soon I will create a project explaining how to carry out the startup of a project in Angular with these characteristics, but meanwhile I leave the following command:
sudo npm install -g pm2
Once installed, I have to copy the root directory (for example, using the scp command) created by the command:
npm run build:ssr
The root directory is by default /dist but it depends on the project configuration. Once the directory has been copied, a file is simply generated with the following code:
// generated by @nguniversal/express-engine
const port = process.env.PORT || 8590;
const server = require('./dist/server');
server.app.listen(port, () => {
console.log(`Listening on: http://localhost:${port}`);
});
With this file created and the pm2 environment installed the following command is executed:
pm2 start node filename.js (in my case server.js)
And we will already have our Server Side Rendering running at the url http://xxxx:8590. If for example we are in an Apache environment, if we add the following three lines to our domain's .conf file we would redirect the requests from port 80 to the Server Side Rendering in the following way:
<VirtualHost www.example.com:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName www.example.com
ServerAlias example.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
It is necessary to have both the apache proxy and proxy_http packages installed and configured.
sudo a2enmod proxy
sudo a2enmod proxy_http
Related technical SEO readings
- How to use Codex inside IntelliJ IDEA. Useful when you want Codex to inspect routes, sitemap, catalog files and SEO metadata before editing.
- Angular SSR SEO with ngx-highlightjs. A practical example of improving code blocks without losing server-side rendering quality.
- Angular routing example. Complements this article because crawlable routes and real links are part of technical SEO.
- ngx-highlightjs in Angular Universal. Useful if your pages include code examples and you want them to remain readable for users and bots.
- Firebase migration in Angular. Connects SEO work with bundle analysis, modern imports and frontend performance.
- hCaptcha with Angular Universal. A related case where browser-only integrations need special care in SSR.
- External JavaScript in Angular. Helps review scripts that can affect rendering, indexing and page stability.
- PageRank and ranking factors. Adds theoretical context about links, authority and why internal linking matters.