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,
});
}
};
السؤال
محمود سعداوي2
السلام عليكم.
عند رفع المشروع على 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" } }
شكرا لكم.
تم التعديل في بواسطة محمود سعداوي23 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.