النطاق: هذا مرجع تنفيذ عملي. راجع توثيق Google والمنصات الحالية قبل اتخاذ قرار إصدار أو سياسة.
ضع سياسة URL واحدة
اختر HTTPS ومضيفًا واحدًا وسياسة trailing slash واحدة وبنية locale واحدة. طبّق redirects على الحافة، ثم اجعل metadataBase وcanonical وsitemap وhreflang والروابط الداخلية متطابقة.
// next.config.js
const nextConfig = {
trailingSlash: false,
async redirects() {
return [{ source: '/:path*', has: [{ type: 'host', value: 'abdallahmekky.com' }], destination: 'https://www.abdallahmekky.com/:path*', permanent: true }]
},
}النمط الصحيح لـgenerateMetadata
استخدم نفس lookup للـslug في المحتوى والـmetadata. لا تبنِ canonical من query string غير موثوق، وأعد notFound قبل إصدار metadata لعنصر غير موجود.
import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
export async function generateMetadata({ params }): Promise<Metadata> {
const { slug } = await params
const page = await getPageBySlug(slug)
if (!page) notFound()
const canonical = new URL('/resources/' + page.slug, SITE_URL)
return { title: page.title, description: page.description, alternates: { canonical: canonical.toString() } }
}في المواقع متعددة اللغات استخدم alternates صريحة: `en` و`ar` و`x-default`، ولا تشير إلى ترجمة غير موجودة.
اختبر العقد النهائي
زحف إلى النسخة النهائية مع slash وبدونه، على المضيفين واللغات ومع query parameters. يجب أن ترى URL واحدًا بحالة 200 وcanonical واحدًا ونسخة واحدة في sitemap. canonical مجرد hint، أما redirect والروابط المتضاربة فتضعفه.
curl -sSI https://example.com/guide/
curl -sS https://www.example.com/guide | grep -i 'canonical\|hreflang'
status == 200
canonical == final_url
sitemap_url == canonical