Koa-router route urls that don't exist
Asked Answered
M

3

7

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.

Missionary answered 24/3, 2015 at 21:1 Comment(1)
I just want to say that I like your markup. matching '*', or router.DEFAULT_ROUTE, etc, would make a lot of sense and probably should be added. I'm thinking about writing up a ull request for that, in fact.Unnamed
I
13

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);
Inaugural answered 24/3, 2015 at 21:31 Comment(0)
M
3

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.

Missionary answered 24/3, 2015 at 21:21 Comment(1)
I just want to point out that this works great. If you have a front end SPA that does or does not use hash marks, it will continue to work because you will server your front end with the url still set as requested.Unnamed
A
1

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

Affirmative answered 28/2, 2022 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.