I have been following (MERN Stack Project: Build a Modern Real Estate Marketplace with react MERN (jwt, redux toolkit)
) tutorial on youtube. under his video he shared also link to his codes (cannot paste it here cuz render wont allow)
My question: The tutorial deploys both the front end and back end to a single URL, but I want to deploy them separately so that the front end has its own URL and the back end has its own URL. I managed to make this work, and here is my working project: (https://real-estate-nms7.onrender.com).
However, I have encountered a problem that only occurs in the production build and not in development mode. When a user goes to the site and clicks “Sign In,” the page appears and everything works. But when the user refreshes that page, I get a “Not Found” error. Another issue is that when a user signs in and navigates to a URL like “mypage link/profile” and then refreshes the page, the same “Not Found” error occurs and the cookies disappear. However, when the user navigates back to “mypage . com”, the cookies reappear and page works.
Can anyone help me understand why this is happening and how to fix it?
Here is my index.js file:
import express from “express”;
import mongoose from “mongoose”;
import dotenv from “dotenv”;
import userRouter from “./routes/user.route.js”;
import authRouter from “./routes/auth.route.js”;
import listingRouter from “./routes/listing.route.js”;
import cors from “cors”;
import cookieParser from “cookie-parser”;
import path from “path”;
dotenv.config();
const PORT = process.env.PORT || 3000;
console.log(“Environment Variables:”);
console.log(“PORT:”, PORT);
console.log(“MONGO:”, process.env.MONGO);
console.log(“JWT_SECERET:”, process.env.JWT_SECERET);
const app = express();
app.use(
cors({
origin: [“…real-estate-nms7. onrender…”],
// origin: [“http://localhost:5173”],
methods: [“POST”, “GET”, “DELETE”],
credentials: true,
})
);
app.use(express.json());
app.use(cookieParser());
mongoose
.connect(process.env.MONGO)
.then(() => {
console.log(“Connected to MongoDB!”);
})
.catch((err) => {
console.log(err);
});
const __dirname = path.resolve();
app.use(“/server/user”, userRouter);
app.use(“/server/auth”, authRouter);
app.use(“/server/listing”, listingRouter);
// Serve static files from the React app
app.use(express.static(path.join(__dirname, “client/dist”)));
// The “catchall” handler: for any request that doesn’t match one above, send back React’s index.html file.
app.get(“*”, (req, res) => {
res.sendFile(path.join(__dirname, “client”, “dist”, “index.html”));
});
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
const message = err.message || “Internal Server Error”;
return res.status(statusCode).json({
success: false,
statusCode: statusCode,
message,
});
});
//l
app.listen(PORT, () => console.log(Server is running on port: ${PORT}
));
// app.get(“/test”, (req, res) => {
// res.json({ message: “Hello World” });
// });
app.get(“/”, (req, res) => {
res.send(“Welcome to the Real Estate API”);
});
here is my cookies code:
import express from "express";
import User from "../models/user.model.js";
import bcryptjs from "bcryptjs";
import { errorHandler } from "../utils/error.js";
import jwt from "jsonwebtoken";
const router = express.Router();
router.post("/signup", async (req, res, next) => {
const { username, email, password } = req.body;
const hashedPassword = bcryptjs.hashSync(password, 10);
const newUser = new User({ username, email, password: hashedPassword });
try {
await newUser.save();
res.status(201).json("User created successfully!");
} catch (error) {
next(error);
// res.status(500).json(error.message);
}
});
router.post("/signin", async (req, res, next) => {
const { email, password } = req.body;
console.log("Request Body:", req.body); // Log the request body for debugging
try {
const validUser = await User.findOne({ email: email });
if (!validUser) return next(errorHandler(404, "User not found!"));
const validPassword = bcryptjs . com pareSync(password, validUser.password);
if (!validPassword) return next(errorHandler(401, "Wrong credentials!"));
// Log the JWT secret and token for debugging
console.log("JWT Secret:", process.env.JWT_SECERET);
const token = jwt.sign({ id: validUser._id }, process.env.JWT_SECERET);
const { password: pass, ...rest } = validUser._doc;
res
.cookie("access_token_voiollamikatahansa", token, {
httpOnly: true,
secure: true,
sameSite: "None",
path: "/",
})
.status(200)
.json(rest);
} catch (error) {
next(error);
// res.status(500).json(error.message);
}
});
router.post("/google", async (req, res, next) => {
try {
const user = await User.findOne({ email: req.body.email });
if (user) {
const token = jwt.sign({ id: user._id }, process.env.JWT_SECERET);
const { password: pass, ...rest } = user._doc;
res
.cookie("access_token_voiollamikatahansa", token, {
httpOnly: true,
secure: true,
sameSite: "None",
path: "/",
})
.status(200)
.json({ ...rest, newUser: false });
} else {
const generatedPassword =
Math.random().toString(36).slice(-8) +
Math.random().toString(36).slice(-8);
const hashedPassword = bcryptjs.hashSync(generatedPassword, 10);
const newUser = new User({
username:
req.body.name.split(" ").join("").toLowerCase() +
Math.random().toString(36).slice(-4),
email: req.body.email,
password: hashedPassword,
avatar: req.body.photo,
});
await newUser.save();
const token = jwt.sign({ id: newUser._id }, process.env.JWT_SECERET);
const { password: pass, ...rest } = newUser._doc;
res
.cookie("access_token_voiollamikatahansa", token, {
httpOnly: true,
secure: true,
sameSite: "None",
path: "/",
})
.status(200)
.json({ ...rest, newUser: true });
}
} catch (error) {
next(error);
}
});
router.get("/signout", async (req, res, next) => {
try {
res.clearCookie("access_token_voiollamikatahansa");
res.status(200).json("User has been logged out!");
} catch (error) {
next(error);
}
});
export default router;