Technical SEO cho Next.js: Core Web Vitals và Beyond
SEO kỹ thuật toàn diện cho Next.js — Metadata API, structured data, tối ưu Core Web Vitals, sitemap, i18n và performance budget.
SEO kỹ thuật quyết định khả năng search engine tìm thấy và xếp hạng nội dung của bạn.
1. Metadata API
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: `${post.title} | Ventra Rocket Blog`,
description: post.excerpt,
alternates: {
canonical: `https://ventrarocket.vn/en/blogs/${post.slug}`,
languages: {
vi: `https://ventrarocket.vn/vi/blogs/${post.slug}`,
en: `https://ventrarocket.vn/en/blogs/${post.slug}`,
},
},
openGraph: {
type: "article",
title: post.title,
publishedTime: post.date,
images: [{ url: post.coverImage, width: 1200, height: 630 }],
},
};
}
2. Structured Data (JSON-LD)
function ArticleJsonLd({ post, locale }: Props) {
const schema = {
"@context": "https://schema.org",
"@type": "TechArticle",
headline: post.title,
author: { "@type": "Organization", name: "Ventra Rocket" },
datePublished: post.date,
inLanguage: locale,
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
3. Tạo Sitemap
// app/sitemap.ts
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const slugs = getBlogSlugs();
const locales = ["vi", "en"];
return [
{ url: "https://ventrarocket.vn", priority: 1, changeFrequency: "daily" },
...locales.flatMap((locale) =>
slugs.map((slug) => ({
url: `https://ventrarocket.vn/${locale}/blogs/${slug}`,
lastModified: new Date(),
changeFrequency: "weekly" as const,
priority: 0.7,
}))
),
];
}
4. Core Web Vitals
LCP < 2.5s — Preload ảnh above-fold:
<Image src="/hero.webp" alt="Hero" priority width={1200} height={600} />
CLS < 0.1 — Luôn khai báo width và height cho ảnh.
INP < 200ms — Defer heavy work:
useEffect(() => {
const id = requestIdleCallback(() => expensiveComputation());
return () => cancelIdleCallback(id);
}, []);
5. Performance Budget trong CI
// lighthouserc.js
module.exports = {
ci: {
assert: {
assertions: {
"categories:performance": ["error", { minScore: 0.85 }],
"categories:seo": ["error", { minScore: 0.95 }],
"largest-contentful-paint": ["error", { maxNumericValue: 2500 }],
},
},
},
};
Kết luận
SEO kỹ thuật toàn diện: metadata, JSON-LD, sitemap, Core Web Vitals, performance budget trong CI. Website Ventra Rocket đạt 90+ điểm PageSpeed sau khi áp dụng các kỹ thuật này.
Bài viết liên quan
Next.js App Router: Patterns cho Production
Hướng dẫn thực chiến xây dựng web app nhanh với Next.js App Router — server components, streaming, parallel routes, caching strategies.
10 TypeScript Pattern giúp code sạch hơn
Tổng hợp 10 TypeScript pattern thực tiễn — từ discriminated unions, template literal types đến satisfies operator — giúp code type-safe và dễ bảo trì.
Quản lý State trong React 2026: Zustand, TanStack Query và URL State
Chọn đúng công cụ quản lý state trong React — TanStack Query cho server state, Zustand cho global UI state, URL cho filter, useState cho local state.