Closed ioanlucut closed 7 years ago
Is there any solution for this?
In my regular hapi flow I do this:
/**
* Trying to catch everything, in order to support vue routing
*/
server.route({
method: 'GET',
path: '/{path*}',
handler: {
directory: {
path: './public',
listing: false,
index: true,
redirectToSlash: true
}
}
});
server.ext('onPreResponse', (request, reply) => {
let response = request.response;
// if 404 - serve Vue app
if (response.isBoom &&
response.output.statusCode === 404) {
return reply.file('./public/index.html');
}
reply.continue();
});
while using webpack dev server it's possible to pass this option:
historyApiFallback: true
While using hapi-webpack-plugin, indeed it returns 404.
@ioanlucut have you found a solution suitable for you?
@SimonDegraeve, @mashaalmemon any hints how this could be accomplished in case of hapi-webpack-plugin
usage?
Regards,
@ioanlucut
So here is the solution which is working for me:
server.ext('onPreResponse', (request, reply) => {
let response = request.response;
// if 404 - serve client app
if (response.isBoom &&
response.output.statusCode === 404) {
return reply.proxy({ uri: `http://${server.info.address}:${server.info.port}/index.html` });
}
return reply.continue();
});
In order to make .proxy
work you need https://github.com/hapijs/h2o2 .
updated, the proxy
scenario works for both cases, despite the fact if we use webpack
or not.
It is an analogue of this express module:
https://github.com/bripkens/connect-history-api-fallback
@ioanlucut @PavelPolyakov,
As I understand it, the plugin intercepts all requests and it makes sense then that any request to a non-existent file will return an error.
However conceivably adjustment could be made to allow for such a scenario.
@SimonDegraeve is the maintainer of this repo. Any thoughts @SimonDegraeve?
Many thanks for the solution.
In the meanwhile I managed to make it work like in the following snippet (I am pasting the whole code for instantiating the dev server).
I am using the html-webpack-plugin
and I need thwindex.html
from compiler memory.
import hapiWebpackPlugin from 'hapi-webpack-plugin';
import bluebird from 'bluebird';
import path from 'path';
import debugFactory from 'debug';
import webpack from 'webpack';
import Hoek from 'hoek';
import config from 'config-loader';
import logger from 'logger';
import HttpStatus from 'http-status-codes';
import webpackConfig from '../config/webpack.config';
import project from '../config/project.config';
import localConfig from '../localConfig';
import serverFactory from './../server';
const debug = debugFactory('app:server');
const APP_NAME = 'app';
// ------------------------------------
// Apply Webpack HMR Middleware
// ------------------------------------
debug('Enabling webpack dev and HMR middleware');
const compiler = webpack(webpackConfig);
const assets = {
publicPath: webpackConfig.output.publicPath,
contentBase: project.paths.client(),
hot: true,
quiet: project.compiler_quiet,
noInfo: project.compiler_quiet,
lazy: false,
stats: project.compiler_stats,
};
const hot = {
path: '/__webpack_hmr',
};
const extraPlugins = [{
register: hapiWebpackPlugin,
options: { compiler, assets, hot },
}];
config.init(localConfig);
logger.init(config.get('/logger'));
const configureForDevEnvironment = (server) => {
server.ext('onPreResponse', (request, reply) => {
const { isBoom, output } = request.response;
if (isBoom && output.statusCode === HttpStatus.NOT_FOUND) {
const filename = path.join(compiler.outputPath, 'index.html');
return bluebird
.fromCallback(cb => compiler.outputFileSystem.readFile(filename, cb))
.then(result => reply(result).type('text/html'))
.catch(err => reply(err).code(HttpStatus.BAD_REQUEST));
}
return reply.continue();
});
};
serverFactory
.create({
connectionSettings: {
port: project.server_port,
},
extraPlugins,
})
.tap(configureForDevEnvironment)
.then(server => server.start((startupError) => {
Hoek.assert(!startupError, startupError);
debug(`${APP_NAME} running at: ${server.info.uri}`);
}))
.catch((error) => {
debug(`${APP_NAME} failed to start: `, error);
throw error;
});
@ioanlucut
thanks, for some reason the trick with the inmemory filesystem didn't worked for me.
I think this solution could be faster then proxy
, however proxy
looks neat.
@PavelPolyakov Indeed - thank you guys for answer - I think for now these solutions are suitable for others who need this.
Hi! First, thanks for the plugin!
The plugin works fine by delivering the
index.html
at/
. However, there's a problem when you are trying to access another route, e.g./customRoute
. This can be solved by adding another custom hook inhapi
check if the response status is404
, and deliver theindex.html
page again.My question is: is there any official way of handling this situation?
Thanks.