Xây dựng một Search-Engine Optimized (SEO) PWA (Progressive web application) bằng Angular – Phần 1
Tác giả: Rajat S
Không quan trọng ứng dụng bạn xây dựng là gì, để nó có thể đến được tay người dùng thì nó phải đến được mắt người dùng trong các kết quả tìm kiếm trước cái đã. Đấy là lý do vì sao Search Engine Optimization (SEO) là một thứ rất quan trọng mà mỗi một lập trình viên khi xây dựng ứng dụng của mình phải chú ý đến.
Trở lại năm 2017, các cuộc khảo sát đã cho thấy rằng, khoảng 27% người dùng điện thoại bỏ qua cửa hàng ứng dụng trên điện thoại của mình, mà tìm đến những công cụ tìm kiếm khác như Google hay Bing.
Chỉ mở cửa hàng ứng dụng trên thiết bị của bạn lên và tìm kiếm một thứ gì đó đơn giản như máy tính bỏ túi chẳng hạn. Thứ bạn nhận được chính là một hằng hà sa số các ứng dụng có thể làm điều tương tự – tính toán.
Điều này chứng tỏ ứng dụng có vị trí top trong các công cụ tìm kiếm là một điều cực kì quan trọng cho mọi lập trình viên. Bởi người dùng tìm kiếm ứng dụng thường không bao giờ xem quá trang đầu hoặc trang hai của kết quả tìm kiếm.
Để hiểu được cách làm việc của công cụ tìm kiếm, hãy xem qua một bài viết khác của Rajat S, “How To Write Better Code in React”.
https://blog.bitsrc.io/how-to-write-better-code-in-react-best-practices-b8ca87d462b0
Nếu bạn vào Google và gõ “React” trên thanh tìm kiếm, thì tại thời điểm Rajat S viết bài này bạn chỉ có thể tìm ra nó ở trang thứ 5!
Nhưng nếu bạn tìm với một từ khóa khác như “better code react”, thì bài của Rajat S sẽ nhảy ngay lên trang nhất!
Vậy là tạm thời đủ về SEO rồi. Giờ hãy cùng xem qua một PWA (Progressive Web App) là gì nhé!
Dựa theo khái niệm của Google, PWAs có một chút khác biệt với ứng dụng mobile truyền thống. Nó giống như là một trang Web được điều chỉnh để có thể chạy trên mobile vậy. Từ khóa ở đây là “Progressive”, nghĩa là đây là những những ứng dụng/websites mà có thể dần được điều chỉnh phù hợp với cài đặt của thiết bị đầu cuối.
Ở bài này, chúng ta sẽ xây dựng một PWA hoàn toàn mới sử dụng Angular. Bạn sẽ tự tay trải nghiệm làm việc với những thứ như “service workes” và “Angular Resolvers”.
BẮT ĐẦU
Xây dựng một Project Angular
Hãy bắt đầu bằng việc tạo mới một Project Angular trên hệ thống của bạn. Nếu bạn chưa cài đặt Angular CLI thì hãy gõ câu lệnh sau vào cửa sổ câu lệnh của bạn:
$ npm install -g @angular/cli
Sau đó, tạo mới một thư mục trên project vừa tạo tên là comicstore
. Để có thể routing trong ứng dụng của chúng ta và sử dụng SASS thay vì CSS truyền thống, thì chúng ta cần phải thêm một số flags sau câu lệnh ng new
như sau:
$ ng new comicstore --routing --style scss // wait for installation to complete $ cd comicstore
Chạy câu lệnh ng serve
để khởi động Angular Development Server. Server sẽ chạy một ứng dụng angular căn bản trên trình duyệt của bạn với địa chỉ mặc định là localhost:4200
.
Nhưng chúng ta không cần những cái mà Angular đã cung cấp sẵn ở đây. Nên hãy loại bỏ nó bằng cách mở file src/app/app.component.html
và thay thế toàn bộ code có sẵn với dòng code sau:
<h1>DC Comics Rebirth</h1>
Bootsrap
Chúng ta sẽ sử dụng Bootstrap khá nhiều ở ứng dụng này, đơn giản bởi vì nó sẽ tiết kiệm thời gian viết HTML và CSS của chúng ta.
Truy cập trang web BootstrapCDN và sao chép đường dẫn cho gói CSS hoàn chỉnh. Sau đó trong thư mục project, mở file style.scss và dán đường dẫn vừa sao chép trong import.
@import url(https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css)
Inline File HTML và Style
Khi mà tôi bắt đầu làm việc với Angular, tôi nhận thấy rằng mỗi component trong Angluar có 4 file:
- File Component Class
- File Component’s HTML mẫu
- File Component’s StyleSheet
- File Component’s Test
Tôi nhận ra rằng mọi thứ sẽ trở nên dễ dàng hơn nếu tôi có thể di chuyển file HTML và file StyleSheet từ các file riêng biệt vào trong file Component Class. Điều này sẽ giảm bớt số lượng file có trong mỗi Component và cũng không phải mở từng file để chỉnh sửa khi muốn sửa code.
Để bắt đầu, xóa file app.component.html
và app.component.scss
từ thư mục src/app
. Sau đó vào file app.component.ts
và đổi tên thuộc tính templateUrl
thành template
. Và cũng đổi nội dung của thuộc tính này như sau:
template: ` <h1>DC Comics Rebirth</h1> <router-outlet></router-outlet> `,
Tương tự, đổi tên thuộc tính styleUrls
thành styles
và thay đổi nội dung như sau:
styles: [` h1{ color: #0476F2; } `]
Chúng ta cũng ần phải cài đặt cho Angular biết rằng chúng ta sẽ viết HTML và Style CSS trong component. Để làm được thế thì chúng ta sử dụng câu lệnh ng config như sau:
$ ng config schematics.@schematics/angular.component.inlineStyle true $ ng config schematics.@schematics/angular.component.inlineTemplate true
Sau đó chúng ta sẽ thấy vài thay đổi với object schematics
trong file angular.json
.
Xây dựng Application Layout
Thay vì tốn thời giờ xây dựng layout từ đầu, chúng ta có thể sử dụng câu lệnh module ui để tạo một ứng dụng đơn giản. Layout này sẽ bao gồm một component cho header, footer và body của layout.
Câu lệnh module ui
được sử dụng với câu lệnh ng generate
như sau:
$ ng generate module ui --module App
Câu lệnh này sẽ tạo ra một thư mục mới tên là ui
bên trong thư mục src/app
. Angular sẽ tạo một dòng code import cho thư mục này trong file app.module.ts
.
Tiếp theo, chúng ta cần tạo component cho Header
, Footer
, và Layout
của ứng dụng.
$ ng generate component ui/containers/layout $ ng generate component ui/containers/header $ ng generate component ui/containers/footer
Những dòng lệnh này sẽ tạo một file component chính và một file test cho mỗi component.
Tiếp theo, mở file app-routing.module.ts
và thêm vào route mặc định cho LayoutComponent
như bên dưới:
const routes: Routes = [{ path: '', component: LayoutComponent, children: [], }];
Bằng cách này, ứng dụng của chúng ta sẽ cài đặt render nội dung của LayoutComponent
. Bạn cũng sẽ thấy rằng ứng dụng của chúng ta vẫn hiển thị tag h1
mà chúng ta đã viết bên trong file app.component.ts
. Để cho đơn giản hơn, hãy di chuyển nó vào trong file layout.component.ts
.
Đầu tiên, vào file app.component.ts
, và xóa mảng styles
. Và cũng xóa tag h1 trong thuộc tính template
.
Bây giờ vào file layout
.component.ts
được đặt ở trong thư mục app/ui/containers/layout
, và viết lại thuộc tính template
như bên dưới:
template: ` <app-header></app-header> <div class="container my-8 py-8"> <router-outlet></router-outlet> </div> <app-footer></app-footer> `,
Nếu bị lỗi trên trình duyệt của bạn, hẳn là Angular chưa import RouterModule
vào file ui.module.ts
. Nếu gặp trường hợp này, hãy xử lý như sau:
@NgModule({ imports: [ CommonModule, RouterModule ], declarations: [ LayoutComponent, HeaderComponent, FooterComponent ] })
Như là tên của của ứng dụng này, thì nó sẽ dùng để lưu truyện tranh. Mà tôi lại là fan của DC Comics, nên tôi sẽ lưu loại này. Vậy nên tôi sẽ vào google và kiếm logo của DC và lưu nó vào thư mục src/assets
với tên là logo.svg
.
Bây giờ ta sẽ thêm logo vào component header
. Mở file header.component.
ts
và thêm vào những thuộc tính sau cho class HeaderComponent
.
public logo = 'assets/logo.svg'; public title = 'DC Comics Rebirth'; public links = [{ label: 'Comics', url: '/Comics', }]
Xóa nội dung của thuộc tính template
. Thay vào đó, chúng ta sẽ thêm vào tag nav như sau:
template: ` <nav class=navbar navbar-expand navbar-blue fixed-top> `
Bạn sẽ để ý rằng ở đây sẽ xuất hiện một dòng màu đen dày ở đầu của trình duyệt. Tiếp theo, hãy thêm vào logo và tiêu đề cho header này. Phía sau tag nav
, thêm vào như sau:
<a routerLink="/" class="navbar-brand"> <img [attr.src]="logo" [attr.alt]="title" width="30" height="30> {{title}} </a>
Chúng ta cũng tạo một đường dẫn tên Comics. Vậy chúng ta cũng sẽ thêm đường dẫn này vào component header. Dưới tag a
, thêm tag div
mới như sau:
<div class="collapse navbar-collpase"> <div class="navbar-nav"> <a class="nav-item nav-link" *ngFor="let link of links" [routerLink]="link.urk" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> {{ link.label }} </a> </div> </div>
Cuối cùng, header của chúng ta sẽ trông như thế này:
Hãy xử lý luôn component footer. Vào file footer.component.
ts
và xóa mọi thứ trong thuộc tính template. Vào thêm vào thẻ nav
trong thuộc tính template
với cùng class như cái ở trong header.
template: ` <nav class="navbar navbar-expand navbar-dark bg-dark fixed-bottom"> `
Ta sẽ thấy xuất hiện viền màu đen lớn ở cuối trang. Đây sẽ là footer của ta. Bạn sẽ có thể viết bất kỳ thứ gì ở đây. Ví dụ như sau:
<div class="navbar-text m-auto text-white"> The comics and characters and everything else presented here belongs to DC Comics. </div>
Lấy dữ liệu trên Angular
Hãy bắt đầu bằng việc tạo mới route tên comic
.
$ ng g m comic --routing
Câu lệnh này sẽ tạo một thư mục mới tên là comic
bên trong thư mục app
.
Mở file app-routing.module.ts
và tạo 2 route ới bên trong mảng children
.
children: [{ path: '', pathMatch: 'full', redirectTo: '/comics', }, { path: 'comics', loadChildren: './comic/comic.module#ComicModule' }],
Route đầu tiên sẽ dẫn người dùng từ route chưa định nghĩa sang route comics
. Route thứ 2 chính là route comics
thật.
Bây giờ khi tải lại trang, nó sẽ tự động dẫn vào route comics
.
Tiếp theo, Hãy thêm module mới tên là comic
:
$ ng g cl comic/models/comic
Bây giờ ta sẽ có một thư mục mới tên là models
bên trong thư mục comic
. Nó sẽ chứa một file tên comic.ts
. Thêm những thuộc tính sau bên trong file này:
export class Comic { public id: string; public name: string; public description: string; public image: string; public price: number; }
Tiếp theo, tạo một cặp container để giúp lấy dữ liệu và truyền dữ liệu đó vào những component khác.
$ ng g c comic/containers/comic-list $ ng g c comic/containers/comic-detail
Những câu lệnh này sẽ tạo ra 2 container components comic-list
và comic-detail
.
Mở file comic-routing.module.ts
và thêm một route vào ComicListComponent
. Đường dẫn của route này sẽ trở thành một chuỗi rỗng. Tương tự, thêm một route vào ComicDetailComponent
với đường dẫn đổi thành :id
.
const routes: Routes = [{ path: '', component: ComicListComponent, }, { path: ':id', component: ComicDetailComponent, }]
Mở file comic-list.component.ts
và đặt thuộc tính template
thành comics
.
template: ` {{comics | json}} `,
Làm điều tương tự cho thuộc tính template
của file comic-detail.component.ts
.
Trong class component của comic-list.component.ts
và comic-detail.component.ts
, thêm một thuộc tính comics
mà có kiểu Comic[]
và khởi tạo nó như một mảng rỗng.
public comic: Comic[] = new Comic();
Sau đó mở file comic-detail.component.ts
và inject ActivatedRoute
trong constructor. Việc này sẽ cho phép truyền thuộc tính id
từ đường dẫn. Và cũng gán this.comic.id
vào this.route.snapshot.paraMap.get('id')
trong ngOnInit
.
constructor(private route: ActivatedRoute) {} ngOnInit() { this.comic.id = this.route.snapshot.paramMap.get('id'); }
Và để chắc chắn rằng ActivatedRoute
được import vào file này:
import { ActivatedRoute } from ‘@angular/router’;
…[Còn tiếp]…
Bài viết gốc được đăng tải tại Blog Bitsrc
- i iOS 18 có gì mới? Có nên cập nhật iOS 18 cho iPhone của bạn?
- G Gamma AI là gì? Cách tạo slide chuyên nghiệp chỉ trong vài phút
- P Power BI là gì? Vì sao doanh nghiệp nên sử dụng PBI?
- K KICC HCMC x TOPDEV – Bước đệm nâng tầm sự nghiệp cho nhân tài IT Việt Nam
- T Trello là gì? Cách sử dụng Trello để quản lý công việc
- T TOP 10 SỰ KIỆN CÔNG NGHỆ THƯỜNG NIÊN KHÔNG NÊN BỎ LỠ
- T Tìm hiểu Laptop AI – So sánh Laptop AI với Laptop thường
- M MySQL vs MS SQL Server: Phân biệt hai RDBMS phổ biến nhất
- S SearchGPT là gì? Công cụ tìm kiếm mới có thể đánh bại Google?
- C Cách tích hợp ChatGPT vào Google Search siêu dễ