make nextJS ignore a subPath in host - javascript

so the problem i'm having is, there is a directory in my public_html file named blog that is not related to my nextJs app, so basically after i deploy the app on host, everything works fine until i choose to check my blog part, for example the url below:
www.sth.com/blog
when i get there, i get the default next 404 page, the problem is, there is actual pages there, and i want my nodeJs server to ignore that exact route so when user goes to www.sth.com/blog, node app kind of ignore it and let it load the basic html pages.
i think it has something to do with my server.js file so here's the code in server.js
also i hosted the app on cpanel if that's important.
const { createServer } = require('http')
const next = require('next')
const isDevMode = process.env.NODE_ENV !== 'production'
const port = process.env.PORT ? process.env.PORT : 3000
const nextjsApp = next({ dev: isDevMode })
const nextjsRequestHandler = nextjsApp.getRequestHandler()
nextjsApp
.prepare()
.then(() => {
createServer((req, res) => {
const url = new URL(req.url, "http://w.w")
nextjsRequestHandler(req, res, url)
}).listen(port, (err) => {
if (err) throw err
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
thank you in advance.

In your server configuration you have to check if request is meant for next or not. If not - you need to respond with your page, instead of passing request further to next:
(req, res) => {
const url = new URL(req.url, "http://w.w");
if (/^\/blog\//.test(url.pathname)) {
// send response with blog
} else {
// pass everything to Next
nextjsRequestHandler(req, res, url);
}
};
Another option would be to split next and not next in two different parts and route requests to them through reverse proxy.

Related

Modify sent text in express.js

I'm trying to make a discord command that stores the user's data in an API. The system looks like this: User runs command -> User's tag gets stored in the API and from there I would be able to handle it from another place. My problem is that after the data is being saved once, it doesn't modify it when another user runs the command.
I have tried doing res.send() to update it and searched on the web for solutions but none of them worked.
Here is my code:
const express = require('express');
const app = express();
app.use(express.json());
const { Client } = require('discord.js');
const client = new Client({ intents: 32767 });
client.on('ready', () => {
console.log('client is now ready')
})
client.on('messageCreate', (msg) => {
if (msg.author.bot) return;
if (msg.content === 'hey') {
app.get('/', (req, res) => {
res.send(`User interacted: ${msg.author.tag}`);
})
}
});
client.login(token)
PS: I do not want to use any programs like Postman etc.
To get the most previous author to show up in the get request, you need to store that value. The app.get/app.post/etc.. methods are defining what the sever should send when particular route is hit. They are not used for storing any data. To solve this particular issue you can simply do something like this:
const express = require('express');
const app = express();
app.use(express.json());
const { Client } = require('discord.js');
const client = new Client({ intents: 32767 });
let previousUser = '';
app.get('/', (req, res) => {
res.send(`User interacted: ${previousUser}`);
})
client.on('ready', () => {
console.log('client is now ready')
})
client.on('messageCreate', (msg) => {
if (msg.author.bot) return;
if (msg.content === 'hey') {
previousUser = msg.author.tag;
}
});
client.login(token)
This code will save the previous messages author to a variable previousUser ever time a message is received that has the content 'hey'. From there, anytime you run a get request on the '/' route, it will display that user.
There are many different ways to store data, be it in memory (like above), in a database, or written to a file. I suggest you read up on express, rest apis, and NodeJS before adding more complicated logic to this program

Connect node app and server + post image to server

I have a very basic question about a node application, and a question about HTTP requests. It's the first time I create a node app with server, and I just can't seem to get the different components to work together.
This is my server.js
var express = require('express');
var multer = require('multer');
const request = require('request');
const upload = multer({dest: __dirname + '/uploads/images'});
const app = express();
const PORT = 3000;
app.use(express.static('public'));
app.post('/upload', upload.single('photo'), (req, res) => {
if(req.file) {
res.json(req.file);
}
else throw 'error';
});
app.listen(PORT, () => {
console.log('Listening at ' + PORT );
});
Then I have a file app.js with a motion-detection system. Every time motion is detected, a picture is taken. This all works fine.
Then the picture should be sent to the server. This is what I can't figure out.
I created a function toServer() that should post the detected data to the server
const request = require('request');
function toServer(data) {
const formData = {
// Pass data via Buffers
my_buffer: data,
// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
};
request.post({url:'http://localhost:3000/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('Upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
};
Problem 1: when running the server.js on localhost:3000, it doesn't find any of the scripts loaded in index.html nor my app.js.
Problem 2: when running the index.html on live-server, all scripts are found, but i get the error "request is not defined".
I am pretty sure there is some basic node setup thing I'm missing.
The solution for toServer() might be more complicated.
Thanks for your time,
Mustard Shaper
Problem 1:
this could happen because you have not specified to render your index.html.
for example:
res.render('index')
if it's not because of the single quotes in upload.single('photo') try double quotes.
Another possible error could be that you are missing a default display engine setting.
an example: https://www.npmjs.com/package/hbs
Problem 2:
it may be because you are missing the header
var request = require('request');
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'http://localhost',
body: "example"
}, function(error, response, body){
console.log(body);
});
See more at https://expressjs.com/

404 - File or directory not found in Next JS

I am making a next js application.
Deployment works fine in vercel.
For deploying the same project in another server, got help from https://stackoverflow.com/a/63660079/13270726 and used the same instructions in our app.
Deployed the out directory into server using ftp client.
Issue
-> When we enter into http://your-domain.com , it works fine. (Even page refresh also works fine in this page)
-> If we move to about page using the url, http://your-domain.com/about then it also works but on page refresh in the url http://your-domain.com/about results in the error,
-> This page refresh also results in the console error like,
Get http://your-domain.com/about Not found
next.config.js: (With public path)
const config = {
webpack: (config, { isServer }) => {
.
.
.
config.devServer = {
historyApiFallback: true
}
config.output.publicPath = "/"
return config;
}
}
module.exports = withPlugins(config);
The issue arises in page refresh only or when we manually type the url.. But while we navigate to it first time then the issue is not there.
Any good help would be much appreciated as I am stuck for long time..
Edit:
I have a server.js file and its code look like,
const dotenv = require("dotenv");
// import ENVs from ".env.local" and append to process
dotenv.config({ path: ".env.local" });
const express = require("express");
const address = require("address");
const chalk = require("chalk");
// create express web server instance
const app = express();
// pull out ENVs from process
const { LOCALHOST, PORT } = process.env;
// get the Local IP address
const LOCALIP = address.ip();
// tell express to serve up production assets from the out directory
app.use(express.static("out" + '/'));
app.get('/*', (req, res) => {
res.send('ok')
});
app.all('*', function(req, res) {
res.redirect('/index.html');
});
// tell express to listen for incoming connections on the specified PORT
app.listen(PORT, (err) => {
if (!err) {
// log the LOCALHOST and LOCALIP addresses where the app is running
console.log(
`\n${chalk.rgb(7, 54, 66).bgRgb(38, 139, 210)(" I ")} ${chalk.blue(
"Application is running at"
)} ${chalk.rgb(235, 220, 52).bold(LOCALHOST)} ${chalk.blue(
"or"
)} ${chalk.rgb(235, 220, 52).bold(`http://${LOCALIP}:${PORT}`)}\n`
);
} else {
console.err(`\nUnable to start server: ${err}`);
}
});

How to reach my backend API in a web host?

I need to access my backend API to send info from a contact form for an email, I deployed my app in a webhost called Kinghost and it gave me two urls the first is generically mywebaddr.com:port-number and the second is mywebaddr.com/site.
I have tried to use both addresses with the function route in the end just like I did in localhost, that in order to work I used http://localhost:4000/contact for example, but it didn't work...
this is my request:
const baseUrl = 'http://mywebsiteurl.com/contact'
const initialState = {
message: {
name: '',
email: '',
subject: '',
main: ''
},
}
export default class ContactUs extends Component {
state = { ...initialState }
reset = () =>{
this.setState({message: initialState.message})
}
send = () => {
const message = this.state.message
const url = baseUrl
console.log(message)
axios.post(url, message)
.then(this.reset())
.then(alert('Message successfully sent!'))
}
this is my index.js (backend)
const express = require('express')
const app = express()
const consign = require('consign')
const port = 4005
consign()
.then('./config/middlewares.js')
.then('./api')
.then('./config/routes.js')
.into(app)
app.listen(port, () => {
console.log(port)
})
my middlewares.js contains cors
const bodyParser = require('body-parser')
const cors = require('cors')
module.exports = app => {
app.use(bodyParser.json())
app.use(cors())
}
Actually, I don't think it's because of my code itself once I can execute everything perfectly in localhost, but somehow I can't get through with the correct URL
I'm new to node and I can't guess what am I doing wrongly, so if someone can help me I'd be really thankful :)
This is not a question for stack-overflow as your issue is not with the application but is with your network.
Anyhow, your API application is running on port 4005. Make sure the port is open with your hosting provider. while your at it make sure your port 4000 is open as well.
after you confirm your firewall settings ill update my answer if your still facing issues.

KoaJS ctx.redirect() causing ERR_TOO_MANY_REDIRECTS in Chrome

I'm new to KoaJS. Playing a bit now. I'm trying to redirect all request to a particular URL using a middle-ware. This seems to product ERR_TOO_MANY_REDIRECTS in Chrome. I tried a lot to debug. Can't get what is wrong.
index.js
// App
const Koa = require('koa')
const app = new Koa()
// Parser
const bodyParser = require('koa-body')
app.use(bodyParser())
// Session
const session = require('koa-session')
app.keys = ['asdfasdf##$ASDf1#$#5rasdf']
app.use(session(app))
// THIS MIDDLEWARE
app.use(async (ctx, next) => {
ctx.session.user = '121' // This is all playground. No production stuff.
const s = ctx.session.user
if (s != '1213') {
ctx.redirect('/login')
}
await next()
})
// Router
const common = require('./routes')
app.use(common.routes())
// Server
app.listen(3000, () => { console.log('Listening on http://localhost:3000') })
routes.js
const Router = require('koa-router')
const router = new Router()
// const User = require('./user')
router.get('/', async ctx => {
ctx.body = 'Home Page'
})
router.get('/login', async ctx => {
ctx.body = 'Login Page'
})
module.exports = router
Consider your middleware:
app.use(async (ctx, next) => {
ctx.session.user = '121' // This is all playground. No production stuff.
const s = ctx.session.user
if (s != '1213') {
ctx.redirect('/login')
}
await next()
})
Because s != '1213' always evaluates to "true", ctx.redirect('/login') is executed for every request.
This will do two things:
set the HTTP response code to 302, telling the browser to perform a redirect
set the Location header to /login, telling the browser to location to redirect to
Considering that this happens for every request, you end up in a loop: a request to / is redirected to /login, which itself is redirected to /login, which is also redirected to /login, ad infinitum. At some point, the browser gives up and issues a ERR_TOO_MANY_REDIRECTS error.
FWIW, after calling ctx.redirect(), you typically end the request, for instance like this:
if (s != '1213') {
return ctx.redirect('/login')
}
In your case, you don't end the request, which means that it will be passed to the router.
To answer your comment, I assume you used this:
if (s != '1213') {
ctx.url = '/login';
}
You change the URL that the router will check to see which handler it should call. Sort of like an internal redirect, or a "rewrite": a request to / is handled internally as if it were a request for /login.
This is not something that you want though, because it may confuse the browser. The correct way is to issue a proper redirect, using ctx.redirect(), which will make the browser change the URL in the location bar and issue a new request.

Categories

Resources