thepassle / app-tools

125 stars 8 forks source link

Router question: redirects with path params #19

Closed JudahGabriel closed 1 year ago

JudahGabriel commented 1 year ago

I want this to work, but it doesn't:

const router = new Router({
  routes: [
    {
      path: '/foo/:name',
      title: 'Foo',
    }
    {
      path: '/legacy/foo/:name',
      title: 'Foo',
      plugins: [
        redirect('/foo/:name'),
      ]
    }
  ]
});

If a user navigates to /legacy/foo/bar, I want it to redirect to /foo/bar.

Unfortunately it navigates to the literal URL /foo/:name

What's the best way to make this work? My thought is to create a plugin that finds the path params and inserts the real values for them. But that seems tedious because I'd have to write code to be aware of different kinds of path params, like :name, :name?, :name+, :name(foo|bar), etc.

Is there a better way?

thepassle commented 1 year ago

We could accept a callback in addition to a string for the redirect plugin, and then pass the context to the callback, e.g.:

redirect((context) => `/foo/${context.params.name}`);

and then change the implementation to something like:

export function redirect(path) {
  return {
    name: 'redirect',
    shouldNavigate: (context) => ({
      condition: () => false,
      redirect: typeof path === 'function' ? path(context) : path
    })
  }
}

Would you be willing to create a PR for that? :)

JudahGabriel commented 1 year ago

Cool. Sure thing, I'll submit a PR.

JudahGabriel commented 1 year ago

PR here.

JudahGabriel commented 1 year ago

Thanks for merging! Closing this issue.