SEO (Search Engine Optimization) คือการปรับหน้าเว็บให้ Search Engine เข้าใจเนื้อหาและแสดงผลได้ดีขึ้น สำหรับ Angular SPA ควรใช้ SSR, Meta Service, Title Service, Open Graph, JSON-LD และ Canonical URL ร่วมกัน
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
subgraph Era1["ยุค Static HTML / Crawl Friendly"]
A["HTML มีเนื้อหาทันที
bot อ่านง่าย"]
end
subgraph Era2["ยุค SPA / JavaScript Content"]
B["Content สร้างด้วย JS
SEO ท้าทาย"]
C["Meta Service
จัดการ tag"]
end
subgraph Era3["ยุค SSR + Rich Preview"]
D["Angular SSR
render บน server"]
E["Open Graph + JSON-LD
social และ structured data"]
end
A --> B --> C --> D --> E
this.meta.updateTag({ name: 'description', content: '...' })this.title.setTitle('หน้าหลัก | เว็บไซต์')og:title, og:description, og:image ช่วย Social Share| Tag/Service | หน้าที่ | ตัวอย่าง |
|---|---|---|
| Title Service | ตั้งชื่อหน้า | `Course |
| description | คำอธิบายหน้า | meta description |
| Open Graph | preview social | og:title, og:image |
| JSON-LD | structured data | Course schema |
| Canonical | URL หลัก | กัน duplicate |
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
A["Route Activated
เปิดหน้า"] --> B["Set Title
ตั้งชื่อหน้า"]
B --> C["Update Meta
description/og"]
C --> D["Add JSON-LD
structured data"]
D --> E["SSR HTML
HTML พร้อม bot อ่าน"]
E --> F["Search/Social Preview
ผลลัพธ์ค้นหาและแชร์"]
// seo.service.ts
// Service กลางสำหรับตั้งค่า SEO ของหน้า
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
@Injectable({ providedIn: 'root' })
export class SeoService {
constructor(
private meta: Meta,
private title: Title,
@Inject(DOCUMENT) private document: Document
) {}
updatePageSeo(options: {
title: string;
description: string;
image: string;
url: string;
}): void {
this.title.setTitle(options.title);
this.meta.updateTag({ name: 'description', content: options.description });
this.meta.updateTag({ property: 'og:title', content: options.title });
this.meta.updateTag({ property: 'og:description', content: options.description });
this.meta.updateTag({ property: 'og:image', content: options.image });
this.meta.updateTag({ property: 'og:url', content: options.url });
this.setCanonical(options.url);
}
private setCanonical(url: string): void {
let link = this.document.querySelector("link[rel='canonical']") as HTMLLinkElement | null;
if (!link) {
link = this.document.createElement('link');
link.setAttribute('rel', 'canonical');
this.document.head.appendChild(link);
}
link.setAttribute('href', url);
}
}
// ตัวอย่างการใช้งาน:
// this.seo.updatePageSeo({ title, description, image, url });
<!-- ตัวอย่าง JSON-LD ใน index.html หรือ component ที่ SSR render -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Course",
"name": "การโปรแกรมบนเว็บ",
"description": "บทเรียนการพัฒนาเว็บแบบ Full-stack"
}
</script>
SeoService