I'm trying to migrate my Express app to hapi.js, and I having trouble with my routes. I just want 2 GET : my index '/', and everything that is not '/' to redirect to '/'.
Using Express I had this:
// static files
app.use(express.static(__dirname + '/public'));
// index route
app.get('/', function (req, res) {
// whatever
}
// everything that is not /
app.get('*', function(req, res) {
res.redirect('/');
});
I have issues with hapi.js to get the same behaviour. My "static road" looks like this:
server.route({
method: 'GET',
path: '/{path*}',
handler: {
directory: {
path: 'public',
listing: false
}
}
});
and my "404 road" would be:
server.route({
method: 'GET',
path: '/{path*}',
handler: function (request, reply) {
reply.redirect('/');
}
});
and I get this error:
Error: New route /{path*} conflicts with existing /{path*}
How can I resolve this?
To handle 404 errors in your hapi app, add a single route that represents a last resort. This route will match all route paths that didn’t fit to any other route in your server. The defined route handler will be applied to GET and POST requests. If you need to handle any other method, add it to the list.
When defining a route in hapi, you need three basic elements: the path, the method, and a handler. These are passed to your server as an object, and can be as simple as the following:
That’s all the magic :) This route handler will catch all routes that don’t match any of your other routes within your hapi server. Because this route has the least restrictions for any paths and parameters, it’ll be called last by hapi. Of course the most interesting part is the result.
If you’re serving HTML views to your client, you might want to display images or provide JavaScript files to enhance the client side functionality. This guide walks you through the setup of hapi to serve static files like images, JavaScript files, compressed archives ( .zip, .tar, etc.).
You're defining 2 routes with the same method and path, which is a conflict as far as hapi's router is concerned. That's why you're getting the error.
If a file isn't found by the directory
handler, it will respond with a 404 error by default.
What you can do is intercept this with an onPreReponse
handler, which checks if the response is an error response (a Boom object), and if so respond however you wish. In your case by redirecting to /
:
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 4000 });
server.route([{
method: 'GET',
path: '/',
handler: function (request, reply) {
reply('Welcome home!');
}
}, {
method: 'GET',
path: '/{p*}',
handler: {
directory: {
path: 'public',
listing: false
}
}
}
]);
server.ext('onPreResponse', function (request, reply) {
if (request.response.isBoom) {
// Inspect the response here, perhaps see if it's a 404?
return reply.redirect('/');
}
return reply.continue();
});
server.start(function () {
console.log('Started server');
});
Recommended reading:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With