q [Error]: Dynamic server usage: Route /api/properties/search couldn't be rendered statically because it used `request.url`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error
at W (/vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:21106)
at Object.get (/vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:28459)
at c (/vercel/path0/.next/server/app/api/properties/search/route.js:1:607)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:36258
description: "Route /api/properties/search couldn't be rendered statically because it used `request.url`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error",
digest: 'DYNAMIC_SERVER_USAGE'
للتوضيح: هذه بعض المكونات التي أشير لي بأنها تحتوي أخطاء علما وأن المشروع يعمل بصفة عادية على المتصفح
api/properties
import cloudinary from "@/config/cloudinary";
import connectDB from "@/config/database";
import Property from "@/models/Property";
import { getSessionUser } from "@/utils/getSessionUser";
/**
* method: GET
* route : /api/properties
*/
export const GET = async (request) => {
try {
await connectDB();
const page = request.nextUrl.searchParams.get("page") || 1;
const pageSize = request.nextUrl.searchParams.get("pageSize") || 5;
const skip = (page - 1) * pageSize;
const total = await Property.countDocuments({});
const properties = await Property.find({}).skip(skip).limit(pageSize);
const result = {
total,
properties,
};
return new Response(JSON.stringify(result), { status: 200 });
} catch (error) {
console.log(error);
return new Response("Something went wrong", { status: 500 });
}
};
/**
* method: POST
* route : api/properties/add
*/
export const POST = async (request) => {
try {
await connectDB();
const sessionUser = await getSessionUser();
if (!sessionUser || !sessionUser.userId) {
return new Response("UserId is required", {
status: 401,
});
}
const { userId } = sessionUser;
const formData = await request.formData();
const amenities = formData.getAll("amenities");
const images = formData.getAll("images").filter((img) => img.name !== "");
const propertyData = {
type: formData.get("type"),
name: formData.get("name"),
description: formData.get("description"),
location: {
street: formData.get("location.street"),
city: formData.get("location.city"),
state: formData.get("location.state"),
zipcode: formData.get("location.zipcode"),
},
beds: formData.get("beds"),
baths: formData.get("baths"),
square_feet: formData.get("square_feet"),
amenities,
rates: {
weekly: formData.get("rates.weekly"),
monthly: formData.get("rates.monthly"),
nightly: formData.get("rates.nightly"),
},
seller_info: {
name: formData.get("seller_info.name"),
email: formData.get("seller_info.email"),
phone: formData.get("seller_info.phone"),
},
owner: userId,
};
// Upload Images To Cloudinary
const imageUploadPromises = [];
for (const image of images) {
const imageBuffer = await image.arrayBuffer();
const imageArray = Array.from(new Uint8Array(imageBuffer));
const imageData = Buffer.from(imageArray);
// Convert The Image Data To Base64
const imageBase64 = imageData.toString("base64");
// Make request to upload to cloudinary
const result = await cloudinary.uploader.upload(
`data:image/png;base64,${imageBase64}`,
{
folder: "propertypulse",
secure: true,
rejectUnauthorized: false,
}
);
imageUploadPromises.push(result.secure_url);
// Wait for all images to upload
const uploadedImages = await Promise.all(imageUploadPromises);
// Add Uploaded images to propertyData object
propertyData.images = uploadedImages;
}
const newProperty = new Property(propertyData);
await newProperty.save();
return Response.redirect(
`${process.env.NEXTAUTH_URL}/properties/${newProperty._id}`
);
// return new Response(JSON.stringify({message: 'success'}), { status: 200 })
} catch (error) {
console.error("This is the error we are looking for: ", error);
return new Response("Failed to add property", { status: 500 });
}
};
/api/properties/search
import connectDB from "@/config/database";
import Property from "@/models/Property";
/**
* method: GET
* route : /api/properties/search
*/
export const GET = async (request) => {
try {
await connectDB();
const { searchParams } = new URL(request.url);
const location = searchParams.get("location");
const propertyType = searchParams.get("propertyType");
const locationPattern = new RegExp(location, "i");
// Match location pattern against database fields
let query = {
$or: [
{ name: locationPattern },
{ description: locationPattern },
{ "location.street": locationPattern },
{ "location.city": locationPattern },
{ "location.state": locationPattern },
{ "location.zipcode": locationPattern },
],
};
// Only check for property if its not 'All'
if (propertyType && propertyType !== 'All') {
const typePattern = new RegExp(propertyType, "i");
query.type = typePattern
}
const properties = await Property.find(query)
return new Response(JSON.stringify(properties), { status: 200 });
} catch (error) {
console.log(error);
return new Response("Something went wrong => Search Properties", {
status: 500,
});
}
};
السؤال
محمود_سعداوي
السلام عليكم.
عند رفع المشروع على vercel، ظهرت الأخطاء التالية:
q [Error]: Dynamic server usage: Route /api/properties/search couldn't be rendered statically because it used `request.url`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error at W (/vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:21106) at Object.get (/vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:28459) at c (/vercel/path0/.next/server/app/api/properties/search/route.js:1:607) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async /vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:36258 description: "Route /api/properties/search couldn't be rendered statically because it used `request.url`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error", digest: 'DYNAMIC_SERVER_USAGE'
للتوضيح: هذه بعض المكونات التي أشير لي بأنها تحتوي أخطاء علما وأن المشروع يعمل بصفة عادية على المتصفح
api/properties
import cloudinary from "@/config/cloudinary"; import connectDB from "@/config/database"; import Property from "@/models/Property"; import { getSessionUser } from "@/utils/getSessionUser"; /** * method: GET * route : /api/properties */ export const GET = async (request) => { try { await connectDB(); const page = request.nextUrl.searchParams.get("page") || 1; const pageSize = request.nextUrl.searchParams.get("pageSize") || 5; const skip = (page - 1) * pageSize; const total = await Property.countDocuments({}); const properties = await Property.find({}).skip(skip).limit(pageSize); const result = { total, properties, }; return new Response(JSON.stringify(result), { status: 200 }); } catch (error) { console.log(error); return new Response("Something went wrong", { status: 500 }); } }; /** * method: POST * route : api/properties/add */ export const POST = async (request) => { try { await connectDB(); const sessionUser = await getSessionUser(); if (!sessionUser || !sessionUser.userId) { return new Response("UserId is required", { status: 401, }); } const { userId } = sessionUser; const formData = await request.formData(); const amenities = formData.getAll("amenities"); const images = formData.getAll("images").filter((img) => img.name !== ""); const propertyData = { type: formData.get("type"), name: formData.get("name"), description: formData.get("description"), location: { street: formData.get("location.street"), city: formData.get("location.city"), state: formData.get("location.state"), zipcode: formData.get("location.zipcode"), }, beds: formData.get("beds"), baths: formData.get("baths"), square_feet: formData.get("square_feet"), amenities, rates: { weekly: formData.get("rates.weekly"), monthly: formData.get("rates.monthly"), nightly: formData.get("rates.nightly"), }, seller_info: { name: formData.get("seller_info.name"), email: formData.get("seller_info.email"), phone: formData.get("seller_info.phone"), }, owner: userId, }; // Upload Images To Cloudinary const imageUploadPromises = []; for (const image of images) { const imageBuffer = await image.arrayBuffer(); const imageArray = Array.from(new Uint8Array(imageBuffer)); const imageData = Buffer.from(imageArray); // Convert The Image Data To Base64 const imageBase64 = imageData.toString("base64"); // Make request to upload to cloudinary const result = await cloudinary.uploader.upload( `data:image/png;base64,${imageBase64}`, { folder: "propertypulse", secure: true, rejectUnauthorized: false, } ); imageUploadPromises.push(result.secure_url); // Wait for all images to upload const uploadedImages = await Promise.all(imageUploadPromises); // Add Uploaded images to propertyData object propertyData.images = uploadedImages; } const newProperty = new Property(propertyData); await newProperty.save(); return Response.redirect( `${process.env.NEXTAUTH_URL}/properties/${newProperty._id}` ); // return new Response(JSON.stringify({message: 'success'}), { status: 200 }) } catch (error) { console.error("This is the error we are looking for: ", error); return new Response("Failed to add property", { status: 500 }); } };
/api/properties/search
import connectDB from "@/config/database"; import Property from "@/models/Property"; /** * method: GET * route : /api/properties/search */ export const GET = async (request) => { try { await connectDB(); const { searchParams } = new URL(request.url); const location = searchParams.get("location"); const propertyType = searchParams.get("propertyType"); const locationPattern = new RegExp(location, "i"); // Match location pattern against database fields let query = { $or: [ { name: locationPattern }, { description: locationPattern }, { "location.street": locationPattern }, { "location.city": locationPattern }, { "location.state": locationPattern }, { "location.zipcode": locationPattern }, ], }; // Only check for property if its not 'All' if (propertyType && propertyType !== 'All') { const typePattern = new RegExp(propertyType, "i"); query.type = typePattern } const properties = await Property.find(query) return new Response(JSON.stringify(properties), { status: 200 }); } catch (error) { console.log(error); return new Response("Something went wrong => Search Properties", { status: 500, }); } };
package.json
{ "name": "next_app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@maptiler/leaflet-maptilersdk": "^2.0.0", "cloudinary": "^2.2.0", "leaflet": "^1.9.4", "leaflet-control-geocoder": "^2.4.0", "leaflet-defaulticon-compatibility": "^0.1.2", "mongodb": "^6.8.0", "mongoose": "^8.4.4", "next": "14.2.4", "next-auth": "^4.24.7", "opencage-api-client": "^1.0.7", "react": "^18", "react-dom": "^18", "react-icons": "^5.2.1", "react-leaflet": "^4.2.1", "react-photoswipe-gallery": "^1.3.9", "react-share": "^5.1.0", "react-spinners": "^0.14.1", "react-toastify": "^10.0.5" }, "devDependencies": { "postcss": "^8", "tailwindcss": "^3.4.1" } }
شكرا لكم.
تم التعديل في بواسطة محمود سعداوي2رابط هذا التعليق
شارك على الشبكات الإجتماعية
3 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.