main
Amir Hossein Moghiseh 2025-02-23 00:04:21 +03:30
parent 04fdf51e7b
commit 5501a66957
5 changed files with 202 additions and 15 deletions

View File

@ -60,7 +60,14 @@ export const generateMetadata = async ({ params }) => {
};
export const viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: false,
// Also supported but less commonly used
// interactiveWidget: 'resizes-visual',
}
export default async function LocaleLayout({
children,

View File

@ -83,17 +83,90 @@ const gql_static = `
query Products($locale:I18NLocaleCode,$start:Int,$limit:Int) {
products(locale: $locale, pagination: { start: $start, limit: $limit }) {
slug
category {
slug
}
brand {
slug
}
}
}
`
const gql_metadata = `
query Products($locale:I18NLocaleCode,$slug:String!) {
products(filters: { slug: { eqi: $slug } }, locale: $locale) {
seo {
id
metaTitle
metaDescription
metaRobots
canonicalURL
metaImage {
documentId
alternativeText
url
}
openGraph {
id
ogTitle
ogDescription
ogUrl
ogType
ogImage {
documentId
alternativeText
url
}
}
structuredData
}
}
}
`
export async function generateMetadata({ params }) {
const { locale, slug } = await params;
// Fetch product SEO data from Strapi GraphQL API
const data = await graphql(gql_metadata, {
locale,
slug,
});
const productSEO = data?.products?.[0]?.seo;
if (productSEO) {
return {
title: productSEO.metaTitle,
description: productSEO.metaDescription,
robots: productSEO.metaRobots || 'index, follow',
// canonical: productSEO.canonicalURL || `https://adhorizonintl.com/product/${slug}`,
alternates: {
canonical: productSEO.canonicalURL || `https://adhorizonintl.com/product/${slug}`,
languages: {
'en': `https://adhorizonintl.com/product/${slug}`,
'ar-OM': `https://adhorizonintl.com/ar-OM/product/${slug}`,
},
},
openGraph: {
title: productSEO.openGraph.ogTitle || productSEO.metaTitle,
description: productSEO.openGraph.ogDescription || productSEO.metaDescription,
url: productSEO.openGraph.ogUrl || `https://adhorizonintl.com/product/${slug}`,
type: productSEO.openGraph.ogType || 'website',
images: [
{
url: productSEO.openGraph.ogImage.url,
alt: productSEO.openGraph.ogImage.alternativeText || 'Product Image',
},
],
},
twitter: {
card: 'summary_large_image',
title: productSEO.metaTitle,
description: productSEO.metaDescription,
images: [productSEO.metaImage?.url],
},
// structuredData: productSEO.structuredData,
};
}
else {
return {}
}
}
export async function generateStaticParams() {
@ -104,11 +177,9 @@ export async function generateStaticParams() {
})
const params = [];
products.forEach((product) => {
params.push({ category: product.category.slug, slug: product.slug })
params.push({ category: product.brand.slug, slug: product.slug })
params.push({ slug: product.slug })
})
return params;
}

View File

@ -1,5 +1,114 @@
import CategoriesData from "src/view/Categories";
const gql_metadata = `
query CategoriesAndBrands($locale:I18NLocaleCode,$slug:String!) {
categories(filters: { slug: { eqi: $slug } }, locale: $locale) {
seo {
id
metaTitle
metaDescription
metaRobots
canonicalURL
metaImage {
documentId
alternativeText
url
}
openGraph {
id
ogTitle
ogDescription
ogUrl
ogType
ogImage {
documentId
alternativeText
url
}
}
structuredData
}
}
brands(filters: { slug: { eqi: $slug } }, locale: $locale) {
seo {
id
metaTitle
metaDescription
metaRobots
canonicalURL
metaImage {
documentId
alternativeText
url
}
openGraph {
id
ogTitle
ogDescription
ogUrl
ogType
ogImage {
documentId
alternativeText
url
}
}
structuredData
}
}
}
`
export async function generateMetadata({ params }) {
const { locale, slug } = await params;
// Fetch product SEO data from Strapi GraphQL API
const data = await graphql(gql_metadata, {
locale,
slug,
});
const productSEO = data?.categories?.[0]?.seo || data?.brands?.[0]?.seo;
if (productSEO) {
return {
title: productSEO.metaTitle,
description: productSEO.metaDescription,
robots: productSEO.metaRobots || 'index, follow',
// canonical: productSEO.canonicalURL || `https://adhorizonintl.com/product/${slug}`,
alternates: {
canonical: productSEO.canonicalURL || `https://adhorizonintl.com/products/${slug}`,
languages: {
'en': `https://adhorizonintl.com/products/${slug}`,
'ar-OM': `https://adhorizonintl.com/ar-OM/products/${slug}`,
},
},
openGraph: {
title: productSEO.openGraph.ogTitle || productSEO.metaTitle,
description: productSEO.openGraph.ogDescription || productSEO.metaDescription,
url: productSEO.openGraph.ogUrl || `https://adhorizonintl.com/products/${slug}`,
type: productSEO.openGraph.ogType || 'website',
images: [
{
url: productSEO.openGraph.ogImage.url,
alt: productSEO.openGraph.ogImage.alternativeText || 'Product Image',
},
],
},
twitter: {
card: 'summary_large_image',
title: productSEO.metaTitle,
description: productSEO.metaDescription,
images: [productSEO.metaImage?.url],
},
// structuredData: productSEO.structuredData,
};
}
else {
return {}
}
}
const CategoryPage = async ({ params }) => {
const _params = await params;
return (

View File

@ -73,7 +73,7 @@ export default function ProductCard({ product }) {
)}
</div>
</div>
<Link href={`/products/${brand?.slug || category?.slug || 'horizon'}/${slug}`.toLowerCase()}
<Link href={`/product/${slug}`.toLowerCase()}
className={`w-full flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors ${locale === "en" ? "flex-row" : "flex-row-reverse"}`}>
{t("Utils.moreDetail")}
<ChevronRight className="h-4 w-4 ml-2" />

View File

@ -84,7 +84,7 @@ const Navbar = ({ items }) => {
}
${theme == 1 ? "bg-gray-100 " : " "}`}
>
<div className={`w-full ${locale === "en" ? "rtl" : "ltr"} px-4 py-4`}>
{/* <div className={`w-full ${locale === "en" ? "rtl" : "ltr"} px-4 py-4`}>
<div className="flex">
<button onClick={changeLocale} className="mr-2 w-fit px-3 p-2 text-sm bg-white flex rounded-xl ">
@ -92,7 +92,7 @@ const Navbar = ({ items }) => {
</button>
</div>
</div>
</div> */}
<div className={`w-full flex p-2 ${locale === "en" ? "ltr" : "rtl"} `}>
<div className="size-[75px] relative p-1 bg-white rounded-lg flex flex-col items-center rounded-tl-2xl justify-center my-auto">
@ -177,9 +177,9 @@ const Navbar = ({ items }) => {
{/* <Link href={"/"} className="w-full"> */}
<div className=" w-full mx-1 flex items-center ">
<button onClick={changeLocale} className="mr-2 w-fit px-3 p-2 h-fit text-sm bg-white flex rounded-xl ">
{/* <button onClick={changeLocale} className="mr-2 w-fit px-3 p-2 h-fit text-sm bg-white flex rounded-xl ">
<p className="mb-0">{locale === "en" ? "العربیه" : "English"}</p>
</button>
</button> */}
</div>
<div className=" ">
<Image