I'm trying to deploy create-react-app using express.js. I'm also using client side routing (react-router-dom v5) with basename my-app.
When I refresh page the following urls via browser:
https://my-website.com/my-app/
https://my-website.com/my-app/something -> everything works fine.
but when I refresh page with url https://my-website.com/my-app/:type/:id (for example: https://my-website.com/my-app/polar/12345.)
I'm getting following error:
Uncaught SyntaxError: Unexpected token '<' --> browser tries to load /js/chunk.js and /js/main.chunk.js files requesting these urls:
https://my-website.com/my-app/polar/12345/static/js/chunk.js
https://my-website.com/my-app/polar/12345/static/js/main.chunk.js
instead of these:
https://mywebsite.com/my-app/static/js/chunk.js
https://mywebsite.com/my-app/static/js/main.chunk.js . -> Files are located at these urls.
here is my express server file:
const path = require('path');
const express = require('express');
const app = express();
const root = path.join(__dirname, 'build');
app.use(express.static(root));
app.get('/*', (req, res) => {
console.log('requested!', req.originalUrl);
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(9000, () => {
console.log('App is running on port 9000');
});
I'm deploying app via docker file into kubernetes cluster on AWS. Pages are served via nginx ingress controller.
Where should be the problem ?
Related
I have created a simple Express JS app. and it is working fine in localhost. when I visit localhost:8000 I see static files (index.html, style.css and frontend.js).
I have tried to deploy that app in a server using cPanel. and I have installed Node app and dependencies using package.json successfully. But when I visit the domain I just see a message (Node JS app is working, Node version is 10.24.1).
How to make my app to point and display the static folder (index.html) and run the app?
My app architecture:
server.js
package.json
public/index.html
public/style.css
public/frontend.js
And here is my server.js startup file:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('public'));
// Setup Server
const port = 8000;
const server = app.listen(port, function(){
console.log(`server running on localhost: ${port}`);
});
//POST Route to store data in the app endpoint, projectData object
app.post('/addData', addData);
function addData (req, res){
let data = req.body;
projectData = data;
console.log(projectData);
}
app.get('/getData', getData);
function getData(req, res) {
res.send(projectData);
}
The problem here is that you are not pointing a route to send the HTML file. Otherwise the client would have to point it to the correct path of the file, Like localhost:3000/index.html.
you need to send it from the server using app.get
app.get("/", (req, res) => {
res.sendFile(__dirname + "path to the file");
});
The problem was that I have created the app in a subfolder of my domain.
But when I have created subdomain and reinstalled the app inside it, the app is pointing to static folder successfully.
I am having an issue with some custom routing code, it all works fine and is in sync with the client-side view routing I do, but as soon as I have a subpage, it doesn't route my static files correctly.
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
Rather than giving me a file from the root directory, it'll serve it as if it were from the subfolder.
Example: i go to http://localhost/sign-up, and files loading in my index file from /scripts are loaded, but if i go to http://localhost/sign-up/2, it'll attempt to load the script from /sign-up/scripts
const express = require('express');
const path = require('path');
const app = express();
app.use('/views', express.static(path.resolve(__dirname, 'frontend', 'views')));
app.use('/styles', express.static(path.resolve(__dirname, 'frontend', 'styles')));
app.use('/scripts', express.static(path.resolve(__dirname, 'frontend', 'scripts')));
app.use('/media', express.static(path.resolve(__dirname, 'frontend', 'media')));
app.get('/*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'frontend', 'newSite.html'));
});
app.listen(process.env.PORT || 1234, () => console.log('Server is now running...'));
To manage this I have been following these tutorials by DCODE on youtube, but I can't see anything amiss:
https://www.youtube.com/watch?v=6BozpmSjk-Y
https://youtu.be/OstALBk-jTc
Resources loaded in the sign up folder should use URLs beginning with a '/' character, to make them relative to the site root, e.g.
src="/scripts/modulefile.js"
href="/css/stylesheet.css"
href="/media/image.png"
and not urls relative to the signup folder - which they will be if the leading '/' is omitted.
You don't need multiple routes to serve your static contents, and the static method of express do such kind of tasks for you:
// If your 'public' or 'static' directory is one of root directories
app.use(express.static(process.cwd() + '/public'));
// so all these requests will be served:
// -> /public/styles/custom.css
// -> /public/scripts/pollyfils.js
// -> /public/media/logo.png
I deployed my MERN app to heroku. It loads, and I can navigate between pages by clicking on the nav bar. But, if I refresh a page, it just comes up blank. There are no error messages on the screen or in the console. If I go back to a previous page that worked before, it also comes up blank. At this point, I don't know what to look for.
My problem stemmed from incorrectly defining the root react route in my server.js file. I got the home page to render and refresh, but then the app would not load any other pages. Here is the server.js file at that point:
const express = require("express");
const mongoose = require("mongoose");
const routes = require("./routes");
const app = express();
// set the port for mongo connection to 3001 in development mode
const PORT = process.env.PORT || 3001;
// Configure body parsing for AJAX requests
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Serve up static assets
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
}
app.use(routes);
mongoose.connect(
process.env.MONGODB_URI || "mongodb://localhost/portfolio_db",
{
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
}
);
// Start the API server on port 3001
app.listen(PORT, () =>
console.log(`🌎 ==> API Server now listening on PORT ${PORT}!`)
);
This sort of fixed my problem, but the app still wasn't routing properly, so I posted this: new issue
Basically, there where 3 problems:
'path' wasn't required at the top of the file, so the path to index.html wasn't defined (had to look at heroku logs to see this error).
The default react route (app.get('*'....)) should not be in the if statement, and
The default react route statement needed to be below the 'app.use(routes)' statement.
I also deleted a statement defining the default react route in /routes/index.js. Now the app deploys and routes correctly.
I was also getting same error "cannot get /page" whenever I did refresh or window.location() So after 3 days of trials and deploys I found this solution. Add this in your server.js file before deploying.
if(process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("/*", function(req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
}); }
You can add this code snippet before app.listen. Remember the path says ./client/build/index.html which references to your build file in the production build in remote heroku master.
cannot get /page happens because the server is not able to find the route which was created using react-router or anything else in frontend so we need to direct the app to index.html in production build so that it starts the whole frontend process again and identifies the route...
My goal is to have dynamic og: tags, that can be seen by the facebook crawler. By doing some research I figured the best (and probably the only) approach is to prerender my app on the server. However I'm having problems with doing that.
I already have an existing Node.js server which looks a little different from the servers in most online guides.
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
// Api for retrieving data from DB
const api = require('./server/api');
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Angular DIST folder
app.use(express.static(path.join(__dirname, 'dist')));
// Api location
app.use('/api', api);
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
})
// Set Port
const port = process.env.PORT || '3040';
app.set('port', port);
const server = http.createServer(app)
server.listen(port, () => console.log('Magic happens on localhost:' + port));
I've tried using prerender.io. I got an API key, installed prerender-node and put this right before redirecting the request to index.html:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
})
I also added this to my index.html:
<meta name="fragment" content="!">
Nothing changed. Perhaps there's something else I need to do to get it working? Again, my goal is to have dynamic og: tags, that can be seen by the facebook crawler.
Additional info: For now, I'm setting the meta tags using the Meta serivce that comes with Angular 4, if it matters.
EDIT:
Demo link if someone wants to test: http://aramet.demo.cdots.bg/news-preview/1
Can you try moving the:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
above the static file line like:
app.use(require('prerender-node').set('prerenderToken', 'my-token'));
// Angular DIST folder
app.use(express.static(path.join(__dirname, 'dist')));
Since your index.html file is in your dist folder and you're serving static files from the dist folder, I'm wondering if the static call is serving your index.html file somehow.
Using Express to serve a Vue.js webpack app, I am receiving the following error after deploy:
Is my code for serving the app is the issue here?
app.use(helmet())
app.use(express.static(path.resolve(__dirname, '../client/dist/static')));
app.all('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../client/dist', 'index.html'));
})
Otherwise isn't express.static supposed to automatically assign content types to the static files?
You get this message also when the response status in 404 Not Found, so check carefully that the files actually exist from Network tab.
Network tab:
Console tab:
See a similar issue here: https://stackoverflow.com/a/48792698/258772
For some reason, had to now specify a mount path:
app.use('/static', express.static(path.resolve(__dirname, '../client/dist/static')));
Yes same problems over here.
I'm using ecstatic (still with express) now. I'm not sure if this is the solution (I'm not on the machine that made the error possible).
Will try it tommorow on the 'error' machine.
const express = require('express');
const ecstatic = require('ecstatic');
const http = require('http');
const app = express();
app.use(ecstatic({
root: `${__dirname}/public`,
showdir: false,
}));
http.createServer(app).listen(8080);
console.log('See if its cool on -> :8080');