Ember app served from express urls don't work after refresh - express

In ember I build for production into the /client folder in my express app. In express at the bottom just before I start the app I have these lines
var api = require('./app/routes/api');
app.use('/api/v'+apiVersion, api);
app.use(express.static(__dirname + '/client'));
That works up until I refresh the page at which point it returns a Cannot GET for that route, in my logs from morgan in the terminal I see it's making a call to /url_here instead of routing to the index.html file and allowing ember to take over from there. Do I need to set this up a different way?

Your express app need to handle 404 error and send 'index.html' of client app.
Add this code at the very bottom (below all others):
app.use('/assets', express.static(__dirname + '/client/assets'));
app.use(function(req, res, next) {
res.sendfile(__dirname + '/client/index.html');
});

Related

How to properly set up Vite, Express, Tailwind web app

Scenario:
I am making a basic web app using Vite & Tailwind. I set up my app as normal installing Vite, and Tailwind, and got everything running fine by testing for Tailwind css on localhost:5500.
Problem:
Once I added an Express server to the mix, and it sends the index.html in response to a 'GET' request # '/', I no longer get the compiled CSS from tailwind.
Is this an uncommon setup that should be troublesome?
You could possibly use a middleware like express.static
Example:
const express = require('express')
const app = express()
app.use(express.static(__dirname + '/public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
In this example, the express.static middleware is used to serve the public directory, which is where the compiled CSS files from Tailwind will be located. Then the express server will send the index.html file in response to a GET request at the root '/' path.
Extra: Alternatively you can also use Webpack or Parcel , which can automatically handle the process of bundling and serving your CSS files

Express is serving files without going through route handlers?

I have the following code:
const app = express();
app.use(express.static(path.resolve('../frontend/dist')));
const server = http.createServer(app);
app.get('/', (req, res) => {
console.log('received request');
res.sendFile(path.resolve('../frontend/dist/index.html'));
});
If I comment out the app.get handler, index.html is served at localhost:3000 anyway, apparently due to the second line. The get handler is not actually executing - received request is never printed in the console.
But without the second line, it can't serve static assets and JS & CSS fail to load. What am I doing wrong here? Why is the static asset config causing the route to be ignored?
express.static() is a generic route handler. It tries to match incoming requests to specific files at a target location in your file system. One of the special features it has is that if it gets a request for / it will look for index.html in the target directory.
You can see the feature described in the doc and, in fact, there's an option { index: false} that can turn the feature off if you don't want it to serve index.html automatically.

Serving static files from an express/node.js application

Hi I am a newbie and started to learn about node recently. I took an Heroku tutorial on websockets (https://devcenter.heroku.com/articles/node-websockets) and adapted it for a specific project I was working on. In the example code there was a single index.html file with some embedded javascript. I moved this script out to a separate file and referenced it in the HTML. Everything worked fine locally but doesn't work when i deploy to Heroko. I chatted with the very helpful team at Heroku who informed me that my server side code is serving up all files as HTML and I need to change the code. They gave me some pointers and I tried as many things as I could over several days but to no avail. In the end they recommended coming to this forum as a way to solve the problem as it is beyond their scope. The existing code that serves up the index.html file is as follows:
const express = require('express');
const SocketServer = require('ws').Server;
const path = require('path');
const PORT = process.env.PORT || 3000;
const INDEX = path.join(__dirname, 'index.html');
const server = express()
.use((req, res) => res.sendFile(INDEX) )
.listen(PORT, () => console.log(Listening on ${ PORT }));
At first i edited this to include the line:
app.use(express.static('public'))
but this didn't work. I then amended as follows and it still doesn't work:
const INDEX = path.join(__dirname, 'index.html');
const JS = path.join(__dirname, 'client.js');
const server = express()
.use((req, res) => {
res.sendFile(INDEX);
res.sendFile(JS);
I have looked at other tutorials that work when i run them in isolation but when I try to adapt my above code it simply doesn't work. I would really appreciate if someone out there could point me in the right direction.
BTW this is what Heroku told me:
"To explain a bit further this error Uncaught SyntaxError: Unexpected token < is because the URL for http://thawing-journey-33085.herokuapp.com/client.js isn't serving a javascript file but is instead trying to serve the HTML for the homepage. This suggests you have an issue with the routing in your application which you'll need to review. This is probably because your server.js file doesn't check for any particular URL before sending the index.html file."
Thanks
I serve my static files like this:
// define the folder that will be used for static assets
app.use(Express.static(path.join(__dirname, '../public')));
// handle every other route with index.html, which will contain
// a script tag to your application's JavaScript file(s).
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, '../public', 'index.html'));
});
This way i set the static folder in the express.static middleware so i can serve the files. And then i redirect all url request to the index.html
To know more: express static

express and static assets with external resources

I am using Express to serve static assets. Frontend is AngularJS 1.x and I have html5mode enabled. Trying to implement Recaptcha is where I noticed the following in Chrome dev tools:
Uncaught SyntaxError: Unexpected token <
api.js?onload=vcRecaptchaApiLoaded&render=explicit“:1
When I click on the function to initiate the Recaptcha process I receive:
Error: reCaptcha has not been loaded yet.
So far this makes sense to be bacause I noticed the string that the first error is reporting is part of the url path to load Recaptcha from Google.
When I click on the url (api.js?onload=vcRecaptchaApiLoaded&render=explicit“:1) in chrome tools it loads my index.html! Strange!
This has be believing it has something to do with my static asset serving. I have played around with my express server until the cows came home and cannot figure out how to remedy.
Live example:
http://ninjacape.herokuapp.com
Here is my code and thank you for taking a look!
index.html
<script src=“https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit“ async defer></script>
express.js
var express = require('express');
var compression = require('compression');
var app = module.exports.prod = exports.prod = express();
var devAPI = 'http://localhost:1337';
app.use(compression());
app.use(express.static('.tmp'));
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/.tmp/index.html');
});
var proxy = require('express-http-proxy');
app.use('/api', proxy(devAPI));
var port = process.env.PORT || 8000;
app.listen(port);
Well... I wish I had a better answer however I am just happy I got it to work. Something in the way I am statically serving files is appending any url in index.html to http://localhost:8000. To work around this I took a look at the actual request coming into Express and found the url. Then added logic to redirect that request to the real url. See commented code below for more info:
// Any requests matching /*
app.get('/*', function(req, res, next) {
// Log the original url express is tying to go to
console.log(req.url);
// This is the url found from the step above (Where are the extra characters coming from?!)
var url ='/%E2%80%9Chttps://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit%E2%80%9C'
// Self explanatory
if (req.url === url) {
// Respond by redirecting the request
res.redirect('https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit')
//End this block and continue
next();
} else {
// If it doesn't match the above url, proceed as normal
res.sendFile(__dirname + '/.tmp/index.html');
}
});

How to Serve Static Content (.html, .js, etc) with Express.JS

Express isn't letting my web application load up AngularJS. My web application has a directory structure that basically looks like this:
\root
server.js
\angularApplication
index.html
\assets
angular.js
My server.js looks like this:
var express = require('express');
var app = express();
app.get("/", function(req, res) {
res.sendFile(__dirname + '/angularApplication/index.html');
});
app.use("/angularScripts", express.static(__dirname + '/angularApplication/assets'));
index.html loads fine, but the script doesn't load. I get this 404 error:
GET http://localhost:8000/angularScripts/angular.js
If I reference AngularJS in my HTML normally:
<script src="/relative-path-to/angular.js"></script>
then Express still won't get the files. What am I doing incorrectly, and why does Express refuse to serve up any my scripts?
The following worked for me:
app.use("/angularJS", express.static(__dirname + '/angularApplication/assets'));
But only if I reference the script in the HTML like this:
<script src="angularJS/angular.js"></script>
Obviously this isn't how app.use is meant to be used. The better solution I've found is this:
app.use(express.static(__dirname + '/angularApplication/assets'));
// app.use(express.static(__dirname + '/angularApplication/etc'));
These will serve up all of the files in the directory, and thus the scripts and stylesheets can be referenced like this instead on the front-end:
<script src="angular.js"></script>