fix(seo): configure canonical links dynamically per page

This commit is contained in:
mstfyldz
2026-05-30 22:14:59 +03:00
parent 7872e8862d
commit 2c24229caa
14 changed files with 37 additions and 5 deletions
+3
View File
@@ -65,6 +65,9 @@ export async function generateMetadata({
return {
title: `${content.title} | Ayris Tech`,
description: content.excerpt,
alternates: {
canonical: `/${lang}/blog/${slug}`,
},
};
}
+3
View File
@@ -9,6 +9,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.blog.title,
description: dict.meta.blog.desc,
alternates: {
canonical: `/${lang}/blog`,
},
};
}
+3
View File
@@ -8,6 +8,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.contact.title,
description: dict.meta.contact.desc,
alternates: {
canonical: `/${lang}/contact`,
},
};
}
+3
View File
@@ -19,6 +19,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: `${titleStr} | ${dict.nav.brandName}`,
description: `${titleStr} - ${dict.work.desc}`,
alternates: {
canonical: `/${lang}/expertise/${slug}`,
},
};
}
+3
View File
@@ -8,6 +8,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.faq.title,
description: dict.meta.faq.desc,
alternates: {
canonical: `/${lang}/faq`,
},
};
}
-1
View File
@@ -55,7 +55,6 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
images: ['/og-image.jpg'],
},
alternates: {
canonical: '/',
languages: {
'en': '/en',
'tr': '/tr',
+3
View File
@@ -8,6 +8,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.home.title,
description: dict.meta.home.desc,
alternates: {
canonical: `/${lang}`,
},
};
}
+3
View File
@@ -8,6 +8,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.process.title,
description: dict.meta.process.desc,
alternates: {
canonical: `/${lang}/process`,
},
};
}
+3
View File
@@ -8,6 +8,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.services.title,
description: dict.meta.services.desc,
alternates: {
canonical: `/${lang}/services`,
},
};
}
+3
View File
@@ -39,6 +39,9 @@ export async function generateMetadata({
return {
title: `${project.title}${dict.nav.brandName}${dict.nav.brandSub}`,
description: project.desc,
alternates: {
canonical: `/${lang}/work/${slug}`,
},
};
}
+3
View File
@@ -9,6 +9,9 @@ export async function generateMetadata({ params }: { params: Promise<{ lang: Loc
return {
title: dict.meta.work.title,
description: dict.meta.work.desc,
alternates: {
canonical: `/${lang}/work`,
},
};
}
+1
View File
@@ -164,6 +164,7 @@ export default function BlogClient({
</div>
<Link
href={`/${lang}/blog/${post.slug}`}
aria-label={content.title as string}
className="w-10 h-10 border border-[#C8C2B8] group-hover:border-[#0A0A0A] group-hover:bg-[#0A0A0A] group-hover:text-[#FFE600] text-[#0A0A0A] flex items-center justify-center transition-all"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
+2 -2
View File
@@ -109,8 +109,8 @@ export default function ContactClient({ lang, dict }: { lang: Locale; dict: any
className="w-full bg-transparent border-b border-[#C8C2B8] focus:border-[#0A0A0A] outline-none py-3 text-sm text-[#0A0A0A] placeholder-[#C8C2B8] transition-colors" />
</div>
<div>
<label className="block font-mono text-[9px] font-bold uppercase tracking-[0.3em] text-[#A0998E] mb-2">{dict.contact.formTrack}</label>
<select value={formState.service} onChange={e => setFormState({ ...formState, service: e.target.value })}
<label htmlFor="form-service" className="block font-mono text-[9px] font-bold uppercase tracking-[0.3em] text-[#A0998E] mb-2">{dict.contact.formTrack}</label>
<select id="form-service" value={formState.service} onChange={e => setFormState({ ...formState, service: e.target.value })}
className="w-full bg-transparent border-b border-[#C8C2B8] focus:border-[#0A0A0A] outline-none py-3 text-sm text-[#0A0A0A] transition-colors cursor-pointer">
<option value="AI Solutions" className="bg-[#F4F0E8]">{dict.services.items.ai.title}</option>
<option value="Blockchain Dev" className="bg-[#F4F0E8]">{dict.services.items.blockchain.title}</option>
+4 -2
View File
@@ -510,6 +510,7 @@ export default function HomeClientBelowFold({ lang, dict }: { lang: Locale; dict
</div>
<Link
href={`/${lang}/blog/${post.slug}`}
aria-label={content.title as string}
className="w-10 h-10 border border-[#C8C2B8] group-hover:border-[#0A0A0A] group-hover:bg-[#0A0A0A] group-hover:text-[#FFE600] text-[#0A0A0A] flex items-center justify-center transition-all"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
@@ -622,13 +623,14 @@ export default function HomeClientBelowFold({ lang, dict }: { lang: Locale; dict
{ label: dict.contact.formTrack, type: "select", options: ["$5k $20k", "$20k $50k", "$50k $100k", "$100k+"] },
].map((field, fi) => (
<div key={fi} className="flex flex-col">
<label className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] mb-3">{field.label}</label>
<label htmlFor={`field-${fi}`} className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] mb-3">{field.label}</label>
{field.type === "select" ? (
<select className="bg-transparent border-b border-[#C8C2B8] focus:border-[#0A0A0A] text-[#0A0A0A] text-sm py-3 focus:outline-none transition-colors cursor-pointer appearance-none">
<select id={`field-${fi}`} className="bg-transparent border-b border-[#C8C2B8] focus:border-[#0A0A0A] text-[#0A0A0A] text-sm py-3 focus:outline-none transition-colors cursor-pointer appearance-none">
{field.options?.map(opt => <option key={opt} value={opt} className="bg-[#F4F0E8]">{opt}</option>)}
</select>
) : (
<input
id={`field-${fi}`}
required
type={field.type}
placeholder={field.placeholder}