+
دیدگاه مخاطبان{" "}
diff --git a/components/AppsComponent/RootData/page.jsx b/components/AppsComponent/RootData/page.jsx
index 3b669a0..a157b6a 100644
--- a/components/AppsComponent/RootData/page.jsx
+++ b/components/AppsComponent/RootData/page.jsx
@@ -202,6 +202,14 @@ const RootData = ({ children }) => {
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/product?${cleanQueryString}`
);
+
+ console.log("rsssssssssssssssssssssssssssssssssssssssss", res);
+ // Check if the response status is 404
+ if (res.status === 404) {
+ // Navigate to the custom 404 page
+ router.push("/404");
+ return; // Exit the function
+ }
const post = await res.json();
setPager(post.pager);
@@ -218,7 +226,6 @@ const RootData = ({ children }) => {
setStopProducts(true); // Assuming this stops pagination
}
-
if (post.products.length <= 19) {
// If the length of fetched products is less than or equal to 19, indicating the last Page
setStopProducts(true); // Assuming this stops pagination
diff --git a/package-lock.json b/package-lock.json
index dec76fb..4b585ff 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,7 +27,8 @@
"react-toastify": "^9.1.3",
"sharp": "^0.33.3",
"simple-react-validator": "^1.6.2",
- "swiper": "^11.0.5"
+ "swiper": "^11.0.5",
+ "xml2js": "^0.6.2"
},
"devDependencies": {
"autoprefixer": "^10.4.16",
@@ -4954,6 +4955,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "node_modules/sax": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+ "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+ },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -5824,6 +5830,26 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
+ "node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/xstate": {
"version": "4.38.3",
"resolved": "https://registry.npmjs.org/xstate/-/xstate-4.38.3.tgz",
diff --git a/package.json b/package.json
index de62835..eeb5132 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,8 @@
"react-toastify": "^9.1.3",
"sharp": "^0.33.3",
"simple-react-validator": "^1.6.2",
- "swiper": "^11.0.5"
+ "swiper": "^11.0.5",
+ "xml2js": "^0.6.2"
},
"devDependencies": {
"autoprefixer": "^10.4.16",
diff --git a/public/images/404.png b/public/images/404.png
new file mode 100644
index 0000000..92bb341
Binary files /dev/null and b/public/images/404.png differ
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..3364299
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,11 @@
+
+User-agent: *
+Allow: /
+Disallow: /cart/*
+Disallow: /cart/checkout/*
+Disallow: /api/*
+Disallow: api.vesmeh.com/*
+Disallow: storage.vesmeh.com/*
+Sitemap: https://vesmeh.com/sitemap.xml
+
+
diff --git a/src/app/404/page.jsx b/src/app/404/page.jsx
new file mode 100644
index 0000000..2f11ada
--- /dev/null
+++ b/src/app/404/page.jsx
@@ -0,0 +1,9 @@
+import NotFoundData from "@comp/AppsComponent/NotFoundData/page";
+import BlogsData from "@comp/Blog/BlogsData/page";
+import React from "react";
+
+const page = async () => {
+ return <>>;
+};
+
+export default page;
diff --git a/src/app/brands/[...id]/page.jsx b/src/app/brands/[...id]/page.jsx
new file mode 100644
index 0000000..82194f1
--- /dev/null
+++ b/src/app/brands/[...id]/page.jsx
@@ -0,0 +1,87 @@
+import BrandData from "@comp/AppsComponent/BrandData/page";
+import ProductData from "@comp/AppsComponent/ProductData/page";
+import { notFound, redirect } from "next/navigation";
+
+async function getData(id) {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/brand/${id}`, {
+ cache: "no-cache",
+ });
+ const post = await res.json();
+ console.log("hi", post);
+ // console.log("object11", post);
+
+ // // Check if the response status is 404
+ if (post.statusCode === 404) {
+ // Navigate to the custom 404 page
+ return notFound(); // Exit the function
+ }
+ return post;
+}
+
+// export async function generateMetadata({ params }) {
+// const data = await getData(params.id[0]);
+
+// const decodedName = decodeURIComponent(params.id[1]);
+// const imageUrl = new URL(
+// data?.product?.files && data?.product?.files[0]?.fileLocation,
+// process.env.STORAGE_URL
+// );
+
+// const metadataUrl = new URL(
+// `products/${params.id[0]}/${data?.product?.persianName}`,
+// process.env.NEXT_PUBLIC_APP_URL
+// );
+// return {
+// title: data?.product?.persianName,
+// description: `خرید ${data?.product?.persianName}| برندهای متنوع با پایین ترین قیمت | فروشگاه اینترنتی وسمه`,
+// metadataBase: metadataUrl,
+// product_id_meta: data?.product?.id,
+// alternates: {
+// canonical: metadataUrl,
+// },
+
+// keywords: [
+// "آرایشی",
+// "بهداشت خانگی",
+// "محصولات زیبایی",
+// "لوازم تمیزی",
+// "مراقبت شخصی",
+// ],
+
+// openGraph: {
+// title: data?.product?.persianName,
+// description: ` خرید ${data?.product?.persianName}| برندهای متنوع با پایین ترین قیمت | فروشگاه اینترنتی وسمه`,
+// images: [imageUrl],
+// url: metadataUrl,
+// type: "website",
+// locale: "fa-IR",
+// type: "website",
+// },
+// twitter: {
+// site: "@vesmehstore",
+// description: ` خرید ${data?.product?.persianName}| برندهای متنوع با پایین ترین قیمت | فروشگاه اینترنتی وسمه`,
+// title: data?.product?.persianName,
+// creator: "@vesmehstore",
+// },
+// other: {
+// product_id: data?.product?.id,
+// product_name: data?.product?.persianName,
+// product_price: data?.product?.costWithDiscount / 10,
+// product_old_price: data?.product?.cost / 10,
+// availability: data?.product?.stock > 0 ? "instock" : "outofstock",
+// guarantee: "guarantee_sample",
+// },
+// };
+// }
+
+const Page = async ({ params }) => {
+ const data = await getData(params.id[0]);
+
+ return (
+ <>
+
+ >
+ );
+};
+
+export default Page;
diff --git a/src/app/categories/[...id]/page.jsx b/src/app/categories/[...id]/page.jsx
index b78aebe..4c37816 100644
--- a/src/app/categories/[...id]/page.jsx
+++ b/src/app/categories/[...id]/page.jsx
@@ -17,6 +17,9 @@ export async function generateMetadata({ params }) {
"لوازم تمیزی",
"مراقبت شخصی",
],
+ alternates: {
+ canonical: `https://www.vesmeh.com/categories/${params.id[0]}/${decodedName}`,
+ },
openGraph: {
title: decodedName,
description: ` خرید ${decodedName}| برندهای متنوع با پایین ترین قیمت | فروشگاه اینترنتی وسمه`,
diff --git a/src/app/not-found.jsx b/src/app/not-found.jsx
new file mode 100644
index 0000000..47ec02a
--- /dev/null
+++ b/src/app/not-found.jsx
@@ -0,0 +1,14 @@
+import NotFoundData from "@comp/AppsComponent/NotFoundData/page";
+import BlogsData from "@comp/Blog/BlogsData/page";
+import { permanentRedirect } from "next/navigation";
+import React from "react";
+
+const getNewLink = async () => {
+ // const data = await fetch("");
+};
+
+const Notfound = async () => {
+ return ;
+};
+
+export default Notfound;
diff --git a/src/app/products/[...id]/page.jsx b/src/app/products/[...id]/page.jsx
index 523ac1a..428f506 100644
--- a/src/app/products/[...id]/page.jsx
+++ b/src/app/products/[...id]/page.jsx
@@ -1,11 +1,19 @@
import ProductData from "@comp/AppsComponent/ProductData/page";
+import { notFound, redirect } from "next/navigation";
async function getData(id) {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/product/${id}`, {
cache: "no-cache",
});
const post = await res.json();
- console.log("object11", post);
+ console.log("hi", post);
+ // console.log("object11", post);
+
+ // // Check if the response status is 404
+ if (post.statusCode === 404) {
+ // Navigate to the custom 404 page
+ return notFound(); // Exit the function
+ }
return post;
}
@@ -27,6 +35,10 @@ export async function generateMetadata({ params }) {
description: `خرید ${data?.product?.persianName}| برندهای متنوع با پایین ترین قیمت | فروشگاه اینترنتی وسمه`,
metadataBase: metadataUrl,
product_id_meta: data?.product?.id,
+ alternates: {
+ canonical: metadataUrl,
+ },
+
keywords: [
"آرایشی",
"بهداشت خانگی",
diff --git a/src/app/sitemap.js b/src/app/sitemap.js
new file mode 100644
index 0000000..970cf2b
--- /dev/null
+++ b/src/app/sitemap.js
@@ -0,0 +1,29 @@
+import xml2js from "xml2js";
+
+async function getData(id) {
+ const res = await fetch(`https://storage.vesmeh.com/site-maps/site-map.xml`, {
+ cache: "no-cache",
+ });
+ const xml = await res.text();
+
+ return xml;
+}
+
+async function parseXml(xml) {
+ const parser = new xml2js.Parser();
+ const result = await parser.parseStringPromise(xml);
+ return result;
+}
+
+export default async function Sitemap() {
+ const xml = await getData();
+ const parsedXml = await parseXml(xml);
+
+ // Construct your sitemap using the parsed XML data
+ const urls = parsedXml.sitemapindex.sitemap.map((entry) => ({
+ url: entry.loc[0],
+ lastModified: entry.lastmod[0],
+ }));
+
+ return urls;
+}
diff --git a/src/app/sitemap.xml/page.jsx b/src/app/sitemap.xml/page.jsx
deleted file mode 100644
index 5138a26..0000000
--- a/src/app/sitemap.xml/page.jsx
+++ /dev/null
@@ -1,9 +0,0 @@
-async function getData(id) {
- const res = await fetch(`https://storage.vesmeh.com/site-maps/site-map.xml`);
- const xml = await res.text();
- return xml;
-}
-
-export default async function Sitemap() {
- return await getData();
-}
diff --git a/src/middleware.js b/src/middleware.js
new file mode 100644
index 0000000..ec7e0f3
--- /dev/null
+++ b/src/middleware.js
@@ -0,0 +1,37 @@
+import { NextResponse } from "next/server";
+import fs from "fs";
+import { permanentRedirect, redirect } from "next/navigation";
+// the following code is taken from : https://nextjs.org/docs/advanced-features/middleware#setting-headers
+export async function middleware(request) {
+ const firstPathname = request.nextUrl.pathname;
+
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_API_URL}/page/redirect/check?oldUrl=${request.nextUrl.pathname}`
+ );
+ if (response.ok) {
+ const newUrl = await response.text();
+ return NextResponse.next({
+ status: 301,
+ headers: {
+ Location: `${process.env.NEXT_PUBLIC_APP_URL}${newUrl}`,
+ },
+ });
+ }
+ return NextResponse.next();
+}
+
+// the following code has been copied from https://nextjs.org/docs/advanced-features/middleware#matcher
+export const config = {
+ matcher: [
+ /*
+ * Match all request paths except for the ones starting with:
+ * - api (API routes)
+ * - _next/static (static files)
+ * - _next/image (image optimization files)
+ * - favicon.ico (favicon file)
+ */
+ "/((?!api|_next/static|_next/image|favicon|fonts|favicon.ico).*)",
+ ],
+};
+
+[];