For those who don't know what SEO is, SEO stands for Search Engine Optimization, it helps people discover your site through search engines like Google, Bing, ...
Take a look at the below picture:
To let search engines discover your site, you must let search engines know your site, for google you can use
Google Search Console but that's another topic, I assume search engines already know your site.
The 3 most important factors are URL, title tag, and meta tag (description, keyword,...). Search engines will look for those 3 things (and many other factors) to compare with the search query and decide whether your site is relevant or not.
UrlTry to use meaningful URLs. For example, instead of using a URL like https://yoursite.com/products/1
use https://yoursite.com/products/iphone or even better https://yoursite.com/iphone . You can achieve this by configuring your rooting modules.
To make slug URLs you can strip accents your product names and join them with a hyphen (-). For example:
Wireless Bluetooth Headphone -> wireless-bluetooth-headphone.
const routes: Routes = [
{
path: 'products/:slugUrl',
component: ProductComponent
}
];
Title & Meta tags
Unfortunately, if you are using Angular SPA (Single Page Application) all search engines except Google can not index (crawl) these tags because these tags are dynamically generated at the client-side (browsers) by javascript, so far only Google has an AJAX crawler which will wait a bit for javascript to generate dynamic HTML before they crawl. Google is the biggest search engine in the world so we are ok with this.
To add title and meta tags you can use
Title and
Meta services from @angular/platform-browser
If you get your items (e.g,.products, news, songs, blogs,...) from an API you can do something like this:
import { Component, OnInit } from '@angular/core';
import { Title, Meta } from '@angular/platform-browser';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.scss']
})
export class ProductComponent implements OnInit {
product: Product;
slugUrl = this.route.snapshot.paramMap.get('slugUrl');
constructor(private route: ActivatedRoute,
private productService: ProductService,
private titleService: Title,
private metaService: Meta) { }
ngOnInit(): void {
this.getProduct();
}
getProduct(): void {
this.productService.get(this.slugUrl).subscribe(result => {
this.product = result;
const title = this.product.name;
const tags = { name: 'keywords', content: this.product.tags};
const description = { name: 'description', content: this.product.description};
this.metaService.updateTag(tags);
this.metaService.updateTag(description);
this.titleService.setTitle(title);
});
}
}
You can also add/update these tags when navigating around your site by pre-configuring these data in your routing modules. I prefer to use both methods, you can pre-config these tags and when there are changes in your controllers (which always happen after navigating events) they will be updated.
In your routing module:
import { ProductListComponent } from './pages/product-list/product-list.component';
import { ProductComponent } from './pages/product/product.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{
path: '',
component: ProductListComponent,
data: {
title: "Products"
}
},
{
path: ':slugUrl',
component: ProductComponent
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductRoutingModule { }
In your app.component.ts
import { Router, NavigationEnd } from '@angular/router';
import { Component } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { filter, map } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private router: Router,
private titleService: Title) {
this.setSEOTags();
}
setSEOTags(): void {
//listen for navigating events
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.router)
)
.subscribe((event) => {
// look for titles in root module settings.
const title = this.getTitle(this.router.routerState, this.router.routerState.root).join(' - ') + ' - YourSiteName';
this.titleService.setTitle(title);
}
);
}
getTitle(state: any, parent: any): string[] {
// get titles from parent and child roots.
const data = [];
if (parent && parent.snapshot.data && parent.snapshot.data.title) {
const title = parent.snapshot.data.title;
if (title) {
data.push(title);
}
}
if (state && parent) {
data.push(... this.getTitle(state, state.firstChild(parent)));
}
return data;
}
}
Above is an example of adding preset titles when navigating around your site.
In your index.html you should add your site title and description, later you can use metaService.updateTag(meta:description) since the tag has already existed.
Note that tags in your index.html are rendered in your server so all search engines can see it.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="keywords" content="keyword 1, keyword 2, keyword 3" />
<meta name="description" content="Your site description" />
<title>Your Site name</title>
<base href="/">
<meta name="referrer" content="strict-origin-when-cross-origin">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
In some cases, Google might not be able to see data rendered on the client-side due to complex javascript, to check whether your SEO data can be seen by Google you can use Google URL Inspection Tool.
That's it for this guide, leave a comment if you need my help, thanks for reading.
Comments
Post a Comment