node http-server to respond with index.html to any request
Asked Answered
J

8

27

I have installed http-server globally.

I launch it from myDir on localhost port 8080. In myDir I have index.html.

If I request (from the browser) http://localhost:8080/ I get index.html, which is OK.

If I request though http://localhost:8080/anything I do not get any response from the server.

What I would like, on the contrary, is that my server always responds with index.html to any http request reaching localhost on port 8080.

Is this possible.

Thanks in advance

Jett answered 28/9, 2016 at 10:5 Comment(3)
-P or --proxy Proxies all requests which can't be resolved locally to the given url. e.g.: -P http://someurl.com => Could you try http-server -P http://localhost:8080/?Center
So did the solution in my answer work for you?Clevie
having a similar issue but I want my dist will serve as 127.0.0.1:8080/myprofile how this will possible when I refresh this will be lost.Mezzosoprano
E
30

Use as specified in the documentation.

http-server --port 8080 -P http://localhost:8080?

Note the ? at the end of the proxy URL.

Enugu answered 12/10, 2020 at 5:24 Comment(3)
This one did the thing! This ? is important.Spindrift
from me this redirects /foo but breaks for /foo/ and /foo/barCherey
on mac zsh http-server --port 8080 -P "http://localhost:8080?"Excise
C
20

To achieve what you are asking for, I recommend you live-server instead of http-server.

live-server --port=8080 --entry-file=./index.html

live-server is also providing a hot-reload but it was not one of your request

Edit: live-server is not designed to be used in production. No gzip compression for example

Edit 2: The maintainer of http-server clearly said in this comment that never, http-server will consider the SPA use-cases

Edit 3: serve seems to be a good option too

Conklin answered 11/5, 2017 at 10:42 Comment(2)
This is useful, specially for those who are attempting to deploy angular app which requires a redirection to index.htmlStem
For using serve: serve . -l 8080 -sScallop
P
8

Simple and straight-forward example using Express 4.x:

var express = require('express');
var app = express();

var path = __dirname + '/public';
var port = 8080;

app.use(express.static(path));
app.get('*', function(req, res) {
    res.sendFile(path + '/index.html');
});
app.listen(port);

This implementation will always respond with index.html if the requested file is not found, and it's almost as simple as using http-server, which lacks this option.

Palomo answered 17/1, 2017 at 11:32 Comment(0)
C
6

Yes there is, with the -P/--proxy option:

http-server -P http://localhost:8080/

Note that any error, 404 included, will redirect to your index, not just missing path.

Center answered 28/9, 2016 at 10:21 Comment(4)
Unfortunately when I do what you suggests I get (on the browser) the following messages This site can’t be reached and 'localhost refused to connect.' and 'ERR_CONNECTION_REFUSED'. On the server I see a stream of requests which end with the server itself throwing an error Error: socket hang upJett
I don't know http-server, but since any error get redirected to index, I assume you got in a loop until the client gave up. I personally would have do as @Clevie did, write your own little server with express, it's easy and fast too.Center
Yes. Accessing http://localhost:8080/anything would redirect to http://localhost:8080/anything and so on. The --proxy option takes the part after host name and port and appends it to the given proxy host/port.Executrix
This is what finally worked for me for serving a local production build of an angular app: http-server -p 8080 --proxy "localhost:8080?" ./distHypogeal
C
3

Sometimes for specific cases like this one, it's easy enough to write your own server:

'use strict';
var host = '127.0.0.1', port = 3333;
var path = require('path');
var app = require('express')();
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
app.listen(port, () => console.log(`Listening on http://${host}:${port}/`));

But keep in mind that if every path returns index.html then in the index.html you cannot reference anything like images, style sheets or client side JavaScript files. Not only with the code shown above but with any solution that sends the same response (index.html) to every request.

You may need to make some exceptions and it's not hard with Express:

'use strict';
var host = '127.0.0.1', port = 3333;
var path = require('path');
var app = require('express')();
app.get('/x.png', (req, res) => res.sendFile(path.join(__dirname, 'x.png')));
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
app.listen(port, () => console.log(`Listening on http://${host}:${port}/`));

Just keep in mind that the exceptions have to go to the top because the first matching route will be used for a given request.

Of course you need to save this code e.g. to app.js, install Express:

npm install express

and start it with:

node app.js

It's more complicated than using a ready solution (though, as you can see, not that complicated either) but you have much more flexibility in how exactly you want it to behave. It's also easy to add logging etc.

Clevie answered 28/9, 2016 at 10:26 Comment(1)
Please explain why that is so ? "But keep in mind that if every path returns index.html then in the index.html you cannot reference anything like images, style sheets or client side JavaScript files. Not only with the code shown above but with any solution that sends the same response (index.html) to every request."Jene
W
2

I've faced this issue while trying to a svelte app build for production. Instead of using http-server I'm using sirv:

first install it npm i --save-dev sirv-cli

then add this script on package.json: "start": "sirv public --single",

Happy coding!

Washing answered 7/12, 2022 at 14:36 Comment(0)
A
0

If you create "Vite" project, it can handle this. vite preview command serves dist folder with single file (index.html) mode.

Albion answered 3/1, 2023 at 13:7 Comment(0)
G
-2

A bit after the war, but anyway. for angular app, I suggest to add to your package.json:

"serve-prod": "cp dist/app-name/index.html dist/app-name/404.html && http-server dist/app-name"

Then call

npm run serve-prod
Gredel answered 10/5, 2020 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.