So I followed a tutorial on how to deploy NextJs app to a subdomain on a Cpanel hosting by adding a server.js file and modifying the Package.json file with the following:
// server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = process.env.port || 3000
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
app.render(req, res, '/a', query)
} else if (pathname === '/b') {
app.render(req, res, '/b', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://${hostname}:${port}`)
})
})
//Package.json file
...
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "NODE_ENV=production node server.js",
"lint": "next lint",
"json-server": "json-server --watch db.json --port 3004"
}
...
I run npm build and uploaded the files to a folder that points to a subdomain. However, when I create my application in Node.js in Cpanel, the "Run NPM Install" button is greyed out and the information I keep getting is that the package.json cannot be found in the folder meanwhile it is actually there.
Any help on what could be wrong or a link to a better tutorial?
Your application root name should be the same with the application url.
Also ensure you uploaded all your file inside your application root name.
The components needed are the .next/ directory and files next.config.js, package.json and server.js, package-lock.json
Click Stop app button and refresh page.
Related
I created Next Js project. I deployed it to my CPanel. And I created server.js file on directory.
I called next module as require in server.js. But When I access to my website I catch an error.
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module 'next';
This error message.
My server.js code
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const dev = process.env.NODE_ENV !== "production";
const port = !dev ? process.env.PORT : 3000;
// Create the Express-Next App
const app = next({ dev });
const handle = app.getRequestHandler();
app
.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
handle(req, res, parsedUrl);
console.log("pathname", pathname);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
My package json
{
"name": "projectName",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"dependencies": {
"express": "^4.17.1",
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}
What should i do?
Thank you.
Best regards
Add this in your package.json dependency section : "#next/env": "^12.0.7"
I've already had problems publishing a next application other than on vercel. To fix the error I had to create a docker in order to publish the application. In case someone doesn't answer with a more viable solution, I recommend looking into using a docker.
Currently I have create-react-app for frontend and express server for backend. In package.json of my create-react-app I use proxy like this "proxy": "http://localhost:5000".
I need to achive the same thing for Next.js app with the same express server.
I just want to be able to use my express server instead of API routes built in Next.js and proxy it like I do in create-react-app.
Do I need to create custom Next.js server even though i'm not changing any of it's functionality? How to do this properly?
yes you have to add custom server in next js
install express js then add file server.js in root directory of next js project
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.use(bodyParser.json())
// add custom path here
// server.post('/request/custom', custom);
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('Ready on http://localhost:5000')
})
})
after that change package.json file script section
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js",
}
I'm running Nuxt in Universal Mode with Koa as API / Controller in the backend based on the Koa template. I'm deploying to Heroku. API works fine locally, but returns 404 in production. I think that the app is running as SPA when deployed as everything else works well.
Here's my server/index.js
const Koa = require('koa')
const consola = require('consola')
const Router = require('koa-router');
const { Nuxt, Builder } = require('nuxt')
const api = require('./api');
console.log('server works'); // ------> This line gets ignored by the Heroku console
const app = new Koa()
const router = new Router();
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = app.env !== 'production'
router.use('/api', api.routes(), api.allowedMethods());
app.use(router.routes());
async function start () {
// Instantiate nuxt.js
const nuxt = new Nuxt(config)
const {
host = process.env.HOST || '127.0.0.1',
port = process.env.PORT || 3000
} = nuxt.options.server
// Build in development
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
} else {
await nuxt.ready()
}
app.use((ctx) => {
ctx.status = 200
ctx.respond = false // Bypass Koa's built-in response handling
ctx.req.ctx = ctx // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
nuxt.render(ctx.req, ctx.res)
})
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`, // ------> Neither this line appears in Heroku console
badge: true
})
}
start()
Procfile
web: nuxt start
Scripts from package.json
"scripts": {
"dev": "cross-env HOST=192.168.1.65 NODE_ENV=development nodemon server/index.js --watch server ",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate",
"test": "ava",
"test:unit": "cross-env TEST=unit ava --config unit.config.js",
"test:e2e": "cross-env TEST=e2e ava --config e2e.config.js",
"heroku-postbuild": "nuxt build"
}
I think I'm getting nu(x)ts after reading all these deployment docs and not seeing the obvious.
Thanks.
I didn't live any problem, attaching my package.json, server/index.js file and Heroku environment settings. You can check herokuapp from here
package.json
{
"name": "testkoa",
"version": "1.0.0",
"description": "My first-class Nuxt.js project",
"author": "Ahmet Zeybek",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate"
},
"dependencies": {
"#nuxtjs/axios": "^5.3.6",
"#nuxtjs/dotenv": "^1.4.0",
"#nuxtjs/pwa": "^3.0.0-0",
"cross-env": "^5.2.0",
"koa": "^2.6.2",
"koa-router": "^7.4.0",
"nuxt": "^2.0.0"
},
"devDependencies": {
"nodemon": "^1.18.9"
}
}
server/index.js
const Koa = require("koa");
const Router = require("koa-router");
const consola = require("consola");
const { Nuxt, Builder } = require("nuxt");
const app = new Koa();
// Import and Set Nuxt.js options
const config = require("../nuxt.config.js");
config.dev = app.env !== "production";
async function start() {
app.use(async function handleError(ctx, next) {
try {
await next();
} catch (err) {
ctx.status = err.statusCode || err.status || 500;
ctx.body = err;
}
});
const router = new Router({ prefix: "/api" });
router.get("/:name", async ctx => {
ctx.response.body = `Hello ${ctx.params.name}`;
});
// Instantiate nuxt.js
const nuxt = new Nuxt(config);
const {
host = process.env.HOST || "127.0.0.1",
port = process.env.PORT || 3000
} = nuxt.options.server;
// Build in development
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
} else {
await nuxt.ready();
}
app.use(router.routes());
app.use(router.allowedMethods());
app.use(ctx => {
ctx.status = 200;
ctx.respond = false; // Bypass Koa's built-in response handling
ctx.req.ctx = ctx; // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
nuxt.render(ctx.req, ctx.res);
});
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
});
}
start();
Heroku Config Vars
HOST=0.0.0.0
NODE_ENV=production
NPM_CONFIG_PRODUCTION=false
You don't need Procfile to use your Nuxt app on Heroku with this
configuration, remove it from your project folder
I am running my Angular Project on npm start and expect it to listen simultaneously to port 3000 (that is suppose to listen automatically to anything that is in the api folder).
Anyway, it looks like it is trying to listen to the port, but it keeps catching an error for who knows what reason
Doing a node BLL.js directly to see if there is a JSON output works like a charm, but having the REST api work does not seem to work weirdly.
package.json
{
"name": "project-vas",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxyConfig.json",
"build": "ng build --env=prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
proxyConfig.json
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"changeOrigin": true
}
}
api/DBConnection.js
exports.config = function()
{
return config = {
user: 'username',
password: 'password',
server: 'localhost',
database: 'databaseName'
};
}
api/BLL.js
const express = require('express');
const path = require('path');
const sql = require('mssql');
const app = express();
const connection = require('./DBConnection');
let config = connection.config();
const port = process.env.PORT || 3000;
app.use(express.static(__dirname + '/dist/ProjectName/'));
app.get('/*', (require, res) => res.sendFile(path.join(__dirname)));
app.get('api/usertypes', function (req, res) {
sql.connect(config, function (err) {
if (err) { console.log(err); }
else {
var request = new sql.Request();
request.query('sp_GETUSERTYPES', function (err, recordset) {
if (err) {
console.log(err);
}
res.send(recordset);
});
}
});
});
environment.ts
export const environment = {
production: false,
api:"http://localhost:3000",
};
Just the expected Stored Procedure output in the shape of a JSON array.
But 'Error occured while trying to proxy to: localhost:4200/api/usertypes' keeps getting returned whenever I try to test it on Postman.
So I tried integrating Stripe into React and it required setting up a node js express server.
The server is well set up and returns build folder of react when deployed to Heroku by some changes I made to my package.json and a new server.js file I wrote.
// package.json
{
...
"scripts": {
"dev": "react-scripts start",
"start": "node server.js",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"heroku-postbuild": "yarn run build"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"proxy": "http://localhost:9000",
"engines": {
"node": "10.15"
}
}
// server.js
const express = require("express");
const app = express();
const path = require("path")
const cors = require("cors")
app.use(express.static(path.join(__dirname, 'build')));
app.use('/charge', express.json());
// app.use(cors())
let whitelist = ['localhost:9000', 'http://myapp.herokuapp.com', 'http://herokuapp.com']
let corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
app.post("/charge", cors(corsOptions), async (req, res) => {
try {
let {amount, tokenId, stripe_key, company_name} = req.body; // params sent in with client
const stripe = require("stripe")(stripe_key); // initializes stripe with the stripe keys passed from client
// console.log(amount, tokenId, stripe_key);
let description = `Payment for posting for ${company_name} on MyApp.io`
let {status} = await stripe.charges.create({
amount,
currency: "usd",
description,
receipt_email: 'emeruchecole9#gmail.com',
source: tokenId
});
console.log(status);
res.json({status});
} catch (error) {
// res.status(500).end();
res.json({error}).end();
console.log(error)
}
});
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname+'/build/index.html'));
});
app.listen(process.env.PORT || 9000, () => console.log("Listening on port 9000"));
I have a Checkout.js file that handles the stripe payment. It sends the generated token to the express server.
The part of the Checkout.js file that sends the POST data to the server is:
axios({
method: 'post',
url: '/charge',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: {
amount: amount*100 || 2000, //this should be dynamic and coming from price of selected tier in tier selection plan
tokenId,
stripe_key,
company_name: company_name || 'Test Inc.'
}
})
The issue is this:
This totally works in dev mode (when I run yarn run dev and then node server.js to fire up the server) and also when I run yarn run build to manually build and yarn run start which fires up the server and serves the build file according to the server.js file above.
But after deploying to heroku and trying the post action, I get a 405 Not Allowed Error. I have tried adding CORS as seen in the server file above but it did not work.
Did you try to add the cors middleware to express
Like
app.use(cors())
Just Add Below code first of your server.js
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
i hope this code help you,it was helpful for me.
also you can read this article:
clickme:)