Redirect respecting sub-routes
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.
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?
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.