Cấu hình Dynamic Hreflang & Subfolder i18n ở lớp Edge Middleware trong Next.js App Router cho 50+ thị trường
Đối với các tập đoàn toàn cầu vận hành dịch vụ trên 50+ quốc gia và vùng lãnh thổ, việc quản lý thẻ Hreflang Tag và điều hướng ngôn ngữ bằng phương pháp khai báo thủ công là một cơn ác mộng kỹ thuật. Chỉ cần một sai sót nhỏ như thiếu liên kết chiều ngược lại (Return Link) hay sai mã quốc gia ISO, Googlebot sẽ vô hiệu hóa hoàn bộ sơ đồ Hreflang của toàn bộ hệ thống!
Giải pháp tiên tiến nhất hiện nay là Xây dựng hệ thống Dynamic Hreflang & Subfolder i18n Routing ngay tại lớp Edge Middleware (Vercel Edge / Cloudflare Workers) trong Next.js 15 App Router. Kỹ thuật này giúp tự động hóa 100% việc sinh thẻ Hreflang và điều hướng ngôn ngữ theo IP với độ trễ phản hồi Server 0ms. Bài viết này sẽ hướng dẫn bạn lập trình từ A-Z.
1. Kiến trúc Subfolder i18n & Dynamic Hreflang ở tầng Edge
Sơ đồ cấu trúc đường dẫn URL chuẩn quốc tế cho 50+ thị trường:
- https://uwmee.com/vi-vn/blog/... (Việt Nam - Tiếng Việt)
- https://uwmee.com/en-us/blog/... (Mỹ - Tiếng Anh)
- https://uwmee.com/ja-jp/blog/... (Nhật Bản - Tiếng Nhật)
- https://uwmee.com/fr-fr/blog/... (Pháp - Tiếng Pháp)
- https://uwmee.com/blog/... (Trang x-default Mặc định)
Luồng xử lý tại Edge Middleware:
Request Truy Cập ➔ Edge Middleware Kiểm tra IP Geo & Cookie ➔ Tự động Rewrite đường dẫn sang Subfolder /lang-country/ ➔ Sinh bộ Thẻ Dynamic Hreflang 2 chiều trong Response Header / Metadata ➔ Googlebot nhận ngay HTML chuẩn 0ms
2. Viết Mã middleware.js Điều hướng i18n Tự động ở Lớp Edge
Tạo file middleware.js ngay tại thư mục gốc của dự án Next.js:
import { NextResponse } from 'next/server';
// Danh sách 50+ mã ngôn ngữ-quốc gia hỗ trợ chính thức
const SUPPORTED_LOCALES = ['vi-vn', 'en-us', 'ja-jp', 'fr-fr', 'de-de', 'es-es'];
const DEFAULT_LOCALE = 'en-us';
export function middleware(request) {
const { pathname } = request.nextUrl;
// Bỏ qua các file tĩnh, hình ảnh và API internal
if (
pathname.startsWith('/_next') ||
pathname.startsWith('/api') ||
pathname.includes('.')
) {
return NextResponse.next();
}
// Kiểm tra xem URL hiện tại đã có mã locale ở đầu chưa
const pathnameHasLocale = SUPPORTED_LOCALES.some(
(locale) => pathname.startsWith('/' + locale + '/') || pathname === '/' + locale
);
if (pathnameHasLocale) return NextResponse.next();
// Đọc vị trí địa lý của khách hàng dựa vào IP header từ Vercel/Cloudflare Edge
const country = (request.geo?.country || '').toLowerCase();
let detectedLocale = DEFAULT_LOCALE;
if (country === 'vn') detectedLocale = 'vi-vn';
else if (country === 'jp') detectedLocale = 'ja-jp';
else if (country === 'fr') detectedLocale = 'fr-fr';
// Chuyển hướng Rewrite ngầm sang đường dẫn chứa Subfolder locale
request.nextUrl.pathname = '/' + detectedLocale + pathname;
const response = NextResponse.rewrite(request.nextUrl);
// Gắn thêm Header ghi nhận locale đã được phát hiện
response.headers.set('X-Edge-Detected-Locale', detectedLocale);
return response;
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
3. Lập trình Tự động Sinh Bộ Thẻ Dynamic Hreflang trong layout.jsx
Tạo file app/[locale]/layout.jsx để sinh tự động bộ thẻ Hreflang hai chiều hoàn chỉnh cho 50+ quốc gia:
import { SUPPORTED_LOCALES, DEFAULT_LOCALE } from '@/lib/i18nConfig';
export async function generateMetadata({ params }) {
const { locale } = await params;
const baseUrl = 'https://uwmee.com';
// Tự động tạo đối tượng languages chứa 50+ đường link Hreflang 2 chiều
const languageLinks = {};
SUPPORTED_LOCALES.forEach((loc) => {
languageLinks[loc] = baseUrl + '/' + loc;
});
// Thêm thẻ chỉ thị x-default cho các quốc gia còn lại
languageLinks['x-default'] = baseUrl + '/' + DEFAULT_LOCALE;
return {
alternates: {
canonical: baseUrl + '/' + locale,
languages: languageLinks, // Tự động inject 50+ thẻ link rel="alternate" hreflang="..."
},
};
}
export default function LocaleLayout({ children, params }) {
return (
<html lang={params.locale}>
<body>{children}</body>
</html>
);
}
Read thêm bài hướng dẫn Thẻ Hreflang x-default là gì trong SEO Quốc tế.
4. 3 Kiểm tra Kỹ thuật Sống còn giúp Hreflang không bị Google vô hiệu hóa
1. Đảm bảo 100% Liên kết Chiều ngược lại (Return Links)
Nếu trang vi-vn chỉ tới trang ja-jp, thì trang ja-jp BẮT BỘC phải xuất hiện thẻ hreflang trỏ lại trang vi-vn. Nhờ đoạn mã lặp SUPPORTED_LOCALES ở trên, 100% các trang con đều sở hữu đầy đủ bộ thẻ liên kết 2 chiều hoàn hảo.
2. Thẻ Canonical phải là Self-referential cho từng Locale
Trang https://uwmee.com/vi-vn/blog phải có thẻ Canonical tự trỏ về chính https://uwmee.com/vi-vn/blog. TUYỆT ĐỐI KHÔNG đặt Canonical của trang tiếng Việt trỏ về trang tiếng Anh! Xem bài Canonical Tag và chống trùng lặp nội dung.
3. Không tự động 301 Redirect Googlebot khi cào dữ liệu
Đối với Googlebot (vốn chủ yếu cào từ IP Mỹ), Edge Middleware của bạn phải để cho Googlebot tự do cào tất cả các Subfolder /vi-vn/, /ja-jp/ mà không ép 301 Redirect về /en-us/. Đoạn code NextResponse.rewrite ngầm ở trên đảm bảo Googlebot cào mượt mà 100% mọi phiên bản ngôn ngữ.
Kết luận
Cấu hình Dynamic Hreflang & Subfolder i18n ở lớp Edge Middleware là giải pháp hạ tầng quy mô lớn nhất giúp các thương hiệu B2B và E-commerce toàn cầu phủ sóng trên 50+ quốc gia. Sự kết hợp giữa tốc độ Edge 0ms và tính chuẩn xác của Hreflang 2 chiều sẽ đưa website của bạn chiếm lĩnh các vị trí dẫn đầu trên bảng xếp hạng Google toàn thế giới.
Câu hỏi thường gặp
Bạn cần giải pháp phần mềm chuyên nghiệp?
Uwmee Software cung cấp dịch vụ 12 tester Google Play & thiết kế website cao cấp giúp nâng tầm thương hiệu của bạn.