hono icon indicating copy to clipboard operation
hono copied to clipboard

Redirect respecting sub-routes

Open riywo opened this issue 1 year ago • 2 comments

What is the feature you are proposing?

Currently, c.redirect(location) simply returns Location: ${location} header: https://github.com/honojs/hono/blob/4ca5f60def726731b3afbf3f6137f0a4b92d8b27/src/context.ts#L533

However, when using sub-routes, each sub-routes need to know their real routes to set the correct location. For example:

const sub = new Hono()
  .get("/", ...)  // <= This is the redirect target.
  .post("/", (c) => {
    return c.redirect("/");     // <= This won't redirect back to "/sub". It's "/" and 404.
    return c.redirect("/sub");  // <= This works but "/sub" is external knowledge injected below.
  });

const app = new Hono()
  .route("/sub", sub);

export default app;

If there is a way to redirect with respecting the sub-routes path, the sub routes don't need to know their real paths and become more decoupled from the main app.

Changing c.redirect()'s behavior would impact the existing applications, so it would be better to introduce a new option e.g. c.redirect(location, { subroute: true }) or a new method.

riywo avatar Mar 09 '24 21:03 riywo

Hi @riywo

You are certainly right! It could have unexpected behavior. I'll give it some thought, but I think I might prefer the method you suggested.

@usualoma How do you think about this matter?

yusukebe avatar Mar 09 '24 21:03 yusukebe

Hi @riywo

Thanks for suggestion! Indeed, we would love to provide a solution to that problem. And I think one good solution would be to have something like c.redirect(location, { subroute: true }).

However, this may not be just a redirection issue. For example, the following dares to use a non-RESTfull URL for the sake of example, but in such an example, the submit destination of the form element cannot be correctly specified.

const sub = new Hono()
  .get('/', (c) => c.html(`
    <form method="post" action="./new-post"> <!-- actual path is /sub/new-post, but submit to /new-post -->
      <button>Submit</button>
    </form>
  `))
  .post('/new-post', (c) => {
    return c.redirect('./') // actual path is /sub, but redirect to /sub/
  })

const app = new Hono()
  .route('/sub', sub)

Given this situation, it might be better to have a method to get the URL in the current application configuration, with a name like c.urlFor(). But well, I think c.urlFor() is a little bit over the top, and I want a simple solution.

usualoma avatar Mar 11 '24 12:03 usualoma