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")}