Next js custom server problem when deployed to cloud - express

I've created a next js custom server feature using express
Everything works fine on localhost but when deployed to google cloud
only the routes from page/api directory is working.
the /test route is not working
Server
const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.get('/test', (req, res) => {
res.send('This is a test page')
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('Now serving on port 3000')
})
})
package.json
"start": "NODE_ENV=production node server.js",

Related

Can't receive a response message when using proxy-middleware between react ui and express backend

I see that the request sent from the ui created using React is forwarded to the backend, but I can't get the response from the ui. There may be details that I missed as I am very new to these issues, thanks in advance :)
//react Login.js
function Login() {
const fetch = actions.fetchUser();
async function handleSubmit() {
try {
fetch();
} catch (err) {
console.error('err', err);
}
}
export default Login;
//index.js
import axios from 'axios';
export const fetchUser = () => async () => {
await axios.get('/api/login');
};
//setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
['/api'],
createProxyMiddleware({
target: 'http://localhost:5000',
}),
);
};
//express app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 5000;
app.use(cors());
app.use(bodyParser.json());
require('./routes/login')(app);
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
// espress login.js
module.exports = app => {
app.get('/api/login', (req, res) => {
console.error('express login');
res.send('login');
});
First of all, do not mix cjs and mjs import/exports.
second of all, you export your middleware but never register/use it. At least your code does not show that part.
Here is very minimal example how you can proxy your react UI via express.
const express = require('express');
const proxy = require('express-http-proxy');
const app = express();
app.get('/api', (req, res) => {
res.send({my: 'data'});
});
// register other routes here
app.use(proxy('http://127.0.0.1:3000'));
app.listen(5000, '0.0.0.0', () => {
console.log('Server is running at http://127.0.0.1:5000');
});
React app content will be available on http://127.0.0.1:5000 with your routes.
And http://127.0.0.1:5000/api will be your express route.
Note: I assume your react app runs on the port 3000

How do I make Heroku to listen to multiple ports?

I am trying to host my application on Heroku but I get the below error from the logs:
Error: listen EADDRINUSE: address already in use :::27427
Apollo Server:
const { ApolloServer } = require("apollo-server");
const typeDefs = require("./server/graphql/typedefs");
const resolvers = require("./server/graphql/resolvers");
const server = new ApolloServer({ typeDefs, resolvers });
server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
console.log(`🚀 Apollo Server ready at ${url} 🚀`);
});
// Express server
const express = require("express");
const app = express();
const cors = require("cors");
app.use(express.json());
app.use(
cors({
origin: "http://localhost:3000",
})
);
const stripe = require("stripe")("sk_test_51Kv9RvGa9sOwxIsovOU0IliCRkL4Qrvi0F1dis4M4Slk1TvEzcuYrx4zBuLZH1iU76ygkDtoXA3Gky6RJEdaBTDa00fDh2Oh1g");
app.post("/create-checkout-session", async (req, res) => {
try {
const session = await stripe.checkout.sessions.create({
customer_email: req.body.email ? req.body.email : undefined,
payment_method_types: ["card"],
mode: "payment",
line_items: req.body.items.map((item) => {
return {
price_data: {
currency: "usd",
product_data: {
name: item.name,
},
unit_amount: item.price * 100,
},
quantity: item.quantity,
};
}),
success_url: `http://localhost:3000/paymentsuccess/${req.body.secret}`,
cancel_url: `http://localhost:3000/paymentfailed/${req.body.secret}`,
});
res.json({ url: session.url });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
app.listen({ port: process.env.PORT || 5001 }, () => {
console.log("🚀 Express server ready at http://localhost:5001 🚀");
});
I think the issue is that I am using both Apollo Server and Express Server in my app. But I need the express for my stripe application. Is there a way so that Heroku can listen to both of my ports?

Failed to load resource: the server responded with a status of 404 (Not Found) on routing

I am trying to route in my project. I want that on clicking connect button the rooms page should get rendered. Home page is working fine but as soon I as click connect it shows Cannot GET /rooms/0b2636b5-c254-47f4-ade8-9e6b745a96d1.The code works fine when instead of routing to rooms it is on root url.
I am new to web development and I tried reading other questions on similar problem but couldn't understand.
Server side(Server.js):
const express = require('express');
const app = express();
const server = require('http').Server(app);
const { v4: uuidV4 } = require('uuid');
const io = require('socket.io')(server);
const { ExpressPeerServer } = require('peer');
const peerServer = ExpressPeerServer(server, {
debug: true
});
app.use('/peerjs', peerServer);
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', (req, res) => {
res.render('home');
})
app.get('/rooms', (req, res) => {
res.redirect(`/rooms/${uuidV4()}`);
})
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
server.listen(3000);
Client Side(script.js)
const socket = io('/rooms');
const videoGrid = document.getElementById('video-grid');
var peer = new Peer(undefined, {
path: '/peerjs',
host: '/rooms',
port: '3000'
})
Navigation bar on home.ejs
<nav class="nav">
<li class="nav-link">
Connect
</nav>
room.ejs
<script>
const ROOM_ID = "<%=roomId%>"
</script>
<script src="/socket.io/socket.io.js" defer ></script>
<script src="script.js" defer></script>
Structure of file
public
-script.js
views
-home.ejs
-room.ejs
server.js
You're really close to it, just 1 mistake in this block:
app.get('/rooms:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
It should be:
app.get('/rooms/:room', (req, res) => {
res.render('room', { roomId: req.params.room })
})
Express documentation page here in case you need it (section Route parameters).

How to serve an index.html in react js in http2

How to serve an index.html in react JS in http2....
like below express code
const express = require('express');
const app = express();
app.use(express.static(`${__dirname}/../build`));
app.all('*', (req, res) => {
res.status(200).sendFile(`${__dirname}/../build/index.html`);
});
console.log('server is running')
const port = 2002;
app.listen(port, () => console.info(`app listening to port ${port} `));

Auth on server side from an isomorphic js app

Hi I'm working on a isomorphic react app that uses passport.js for auth.
My problem is requests can come from the client, or from the server. If the request comes from the client, it's authenticated and all is good. BUT, if the request comes from the server, then the auth fails :(
Server (lots removed for sake of clarity):
server.use('/api/data', require('./api/data'));
server.get('*', async (req, res, next) => {
await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
<div>
{component}
</div>
);
data.css = css.join('');
});
});
/api/data:
router.get('/', auth.isAuthenticated, async (req, res, next) => {
res.status(200).send({result: 'working!'});
});
Routes:
on('/route', async (state, next) => {
// RESP IS A REJECTED RESPONSE :(
const resp = await fetch('/api/data');
const data = await resp.json();
return <Component data={data} />;
});