By TTTTT TTTTT
Hi,
I have been having recent problems with my MERN project. I was trying to change my code for logging in and signing up users but kept getting 404 errors and wasn’t sure why.
I decided to visit my Explore page and noticed that my GET requests for getting all posts was also getting a 404.
I then decided to visit the ip address for my droplet and saw the same 404 error for the GET requests for all posts in the Explore page.
When I do GET Requests to /api/blog/posts or to /api/users/users using POSTMAN I see the index.html page from React. When before I would a list of all posts or all users from my MongoDB database.
I decided to remove all of the changes I did today and I still see the errors. Yesterday I wasn’t getting these errors.
I’m not sure if its something that I did or if it’s nginx.
Any help would be appreciated.
NGINX
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/*PROJECT NAME*/client/build/index.html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name *DO IP ADDRESS*;
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control public;
}
location / {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:3000;
client_max_body_size 50M;
}
location = /favicon.ico {
log_not_found off;
}
}
interceptor.js
const axiosPrivate = axios.create({
baseURL: `${process.env.REACT_APP_URL}/api`
});
Explore.js
useEffect(() => {
const fetchPosts = _async_ () => {
try {
let response = await axiosPrivate.get('/blog/posts')
setPostsLoaded(response.data)
setLatestPosts(response.data.slice(-5))
setShowLatestPosts(true)
} catch (error) {
console.log(error);
}
}
fetchPosts()
}, [])
blogAPI
_// list_
router.get('/posts', (req, res, next) => {
PostService.list()
.then((posts) => {
res.status(200)
res.json(posts)
})
})
PostsController
class PostService {
_// list_
_static_ list() {
return Post.find({})
.then((posts) => {
return posts
})
}
_// find_
_static_ find(id) {
return Post.findById(id)
.then((post) => {
return post
})
}
}
Server.js
require('dotenv').config()
const path = require("path")
const express = require('express')
const mongoose = require('mongoose')
const cookieParser = require('cookie-parser')
const app = express()
const blogAPI = require('./api/blogApi')
const auth = require('./api/auth')
const users = require('./api/users')
_/* Connect to Database */_
mongoose.connect(process.env.DBURI, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => console.log('MongoDB connected...'))
.catch(err => console.log(err))
app.use(cookieParser())
_/* POST form handling */_
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
_/* Routing */_
app.use('/api/blog', blogAPI)
app.use('/api/auth', auth)
app.use('/api/users', users)
app.use('/public', express.static(path.join(__dirname, 'public')))
// Have backend display react build folder in production
app.use(express.static(path.join(__dirname, '/../client', 'build')))
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, '/../client', 'build', 'index.html'))
});
app.listen(process.env.PORT, () => console.log("Server started!"))
module.exports = app;
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi there,
There are a few things that I could suggest here:
Note that it is recommended to take a backup of your work before making any changes so that if anything goes wrong you could always revert back to a working version.
This might be happening because the React app is not able to route the API requests correctly, and it’s serving the React app’s index.html instead of the actual API response. What you could do here is to update the location / block in your NGINX configuration to the following:
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:3000;
client_max_body_size 50M;
}
That way the React app will be served from the / location and the Node.js API will be served from the /api location.
This could be because your Node.js server is not running or it’s crashing due to an error. Make sure your server is running and check the logs for any error messages. You can start with the following:
tail -100 /var/log/nginx/error.logroot directive should point to the directory, not the file. eg:root /var/www/*PROJECT NAME*/client/build;
process.env.REACT_APP_URL variable in the interceptor.js file has the correct value. It should point to your DigitalOcean Droplet’s IP address or your domain name with the appropriate protocol (http or https).Let me know how it goes after those changes!
As a side note, keep in mind that once you make a change to the Node.js project and the Nginx configuration you need to restart them. A good practice is to run nginx -t before restarting Nginx to make sure that there are no configuration errors.
Best,
Bobby
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.