diff --git a/src/app/[locale]/layout.jsx b/src/app/[locale]/layout.jsx index 69d99f4..01e5501 100644 --- a/src/app/[locale]/layout.jsx +++ b/src/app/[locale]/layout.jsx @@ -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, diff --git a/src/app/[locale]/products/[category]/[slug]/page.jsx b/src/app/[locale]/product/[slug]/page.jsx similarity index 68% rename from src/app/[locale]/products/[category]/[slug]/page.jsx rename to src/app/[locale]/product/[slug]/page.jsx index cd3560e..30e9979 100644 --- a/src/app/[locale]/products/[category]/[slug]/page.jsx +++ b/src/app/[locale]/product/[slug]/page.jsx @@ -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; - } diff --git a/src/app/[locale]/products/[category]/page.jsx b/src/app/[locale]/products/[category]/page.jsx index 1546872..1ecea0d 100644 --- a/src/app/[locale]/products/[category]/page.jsx +++ b/src/app/[locale]/products/[category]/page.jsx @@ -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 ( diff --git a/src/components/Cards/CardNormal/index.jsx b/src/components/Cards/CardNormal/index.jsx index 7bc05f0..2f9c0e6 100644 --- a/src/components/Cards/CardNormal/index.jsx +++ b/src/components/Cards/CardNormal/index.jsx @@ -73,7 +73,7 @@ export default function ProductCard({ product }) { )} - {t("Utils.moreDetail")} diff --git a/src/components/NavBar/index.jsx b/src/components/NavBar/index.jsx index 78f3d5f..2cac028 100644 --- a/src/components/NavBar/index.jsx +++ b/src/components/NavBar/index.jsx @@ -84,7 +84,7 @@ const Navbar = ({ items }) => { } ${theme == 1 ? "bg-gray-100 " : " "}`} > -
+ {/*
-
+
*/}
@@ -177,9 +177,9 @@ const Navbar = ({ items }) => { {/* */}
- + */}