basickarl
basickarl

Reputation: 40504

Koa-router route urls that don't exist

I can't believe there is no easy answer to do this. I wish to redirect let's say;

www.example.com/this-url-does-not-exist

to

www.example.com/

There has to be a way, all the nodejs websites with koajs just can't crash? Heres my router (I'm using koa with koa-router):

router
    .get('/', function* (next) {
        this.body = "public: /";
    })
    .get('/about', function* (next) {
        this.body = "public: /about";
    })
    .get('*', function* (next) { // <--- wildcard * doesn't work
        this.body = "public: *";
    });

And don't tell me to use regular expressions, I've been trying and with them and it means manually updating the expression when adding urls etc. which is not what I've looking for, plus it doesn't work as javascript does not support negative lookbehinds.

Upvotes: 7

Views: 7838

Answers (3)

HereBeAndre
HereBeAndre

Reputation: 308

Even though James Moore's answer works great, support for generators will be removed in koa v3. In order to convert the "old" generator middleware into its new async-await version:

app.use(async (ctx, next) => {
    await next();
    ctx.redirect("/someotherurl");
});

I've implemented routing with @koa/router and I have the routes in a separate file. Anyway, I've simply added the above function right before app.listen(). Here's how I handled redirection:

const Koa = require("koa");
const bodyParser = require("koa-bodyparser");
const productRoutes = require("../src/routes/products.routes");
require("./db/index");

const port = process.env.PORT || 3000;
const app = new Koa();

app.use(bodyParser());
app.use(productRoutes.routes()).use(productRoutes.allowedMethods());
app.use(async (ctx, next) => {
    await next();
    ctx.redirect("/products");
});

app.listen(port, () => {
    console.log(`Server up on port ${port}`);
});

Official docs here: https://github.com/koajs/koa/blob/master/docs/migration.md#upgrading-middleware

Upvotes: 1

basickarl
basickarl

Reputation: 40504

JAMES MOORES ANSWER IS CORRECT; DO NOT LISTEN TO MEH!

publicRouter
    .get('/', function* (next) {
        console.log('public: /');
        this.body = 'public: /';
    })
    .get('/about', function* (next) {
        console.log('public: /about');
        this.body = 'public: /about';
    })
    .get(/(|^$)/, function* (next) { // <--- important that it is last
        console.log('public: /(|^$)/');
        this.body = 'public: /(|^$)/';
    });

Koa-router fails to inform that .get is dependent on the order they are added in code. So putting it at the end with the regex /(|^$)/ works.

This does however interfere when using koa-mount to mount other routers.

Upvotes: 3

James Moore
James Moore

Reputation: 1901

If you prefer no regex do something like this:

var koa   = require('koa'),
    router = require('koa-router')(),
    app   = koa();


router.get('/path1', function *(){
    this.body = 'Path1 response';
});

router.get('/path2', function *(){
    this.body = 'Path2 response';
});

app.use(router.routes())
app.use(router.allowedMethods());

// catch all middleware, only land here
// if no other routing rules match
// make sure it is added after everything else
app.use(function *(){
  this.body = 'Invalid URL!!!';
  // or redirect etc
  // this.redirect('/someotherspot');
});

app.listen(3000);

Upvotes: 13

Related Questions