URL builder
This guide covers building URLs for routes in Tinka. You will learn how to:
- Name routes
- Build a route's URL with its parameters
- Add a query string
- Know how values are escaped
- Catch links to routes that don't exist
Overview
Links and redirects that repeat a route's path break when the path changes, and a path assembled by hand goes wrong in ways tests rarely catch: a title with a / or ? in it ends up in the wrong place. Named routes solve both. You name a route once, where you register it, and build its URL from the name everywhere else, with every value escaped for its place.
Name a route
As names the route it's called on. Names are unique, and dots group related routes by convention:
app.Get("/posts", listPosts).As("posts.index")
app.Get("/posts/{id}", showPost).As("posts.show")
app.Route("/teams/{team}", func(r *tinka.Router) {
r.Get("/members/{id}", showMember).As("teams.members.show")
})
app.Get("/docs/{path...}", showDoc).As("docs.show")A route inside Route keeps its full path, so its URL includes the prefix.
Build a URL
URL takes a route's name and one value for each of its parameters, in order, and returns the path. Strings, integers and any fmt.Stringer work as values:
app.URL("posts.index") // /posts
app.URL("posts.show", 7) // /posts/7
app.URL("teams.members.show", "go", 42) // /teams/go/members/42A handler that redirects after creating a post builds the new post's URL the same way:
func (h Posts) Create(c *tinka.Ctx) (tinka.Response, error) {
post, err := h.Service.Create(c, "Second post")
if err != nil {
return nil, err
}
return tinka.Redirect(h.App.URL("posts.show", post.ID)), nil
}URL is a method of every *tinka.Router, so code that registers routes inside a group can build URLs too.
Add a query string
Pass a url.Values after the parameters, and it becomes the query string:
app.URL("posts.index", url.Values{"page": {"2"}, "tag": {"go"}}) // /posts?page=2&tag=goHow values are escaped
Each value is escaped for its place, so it always reaches the route as the same value. A {name} parameter is one path segment, so a / in the value is escaped too. A {name...} wildcard keeps the slashes of its value and escapes each segment:
app.URL("posts.show", "a/b?c") // /posts/a%2Fb%3Fc
app.URL("docs.show", "guides/basics/routing") // /docs/guides/basics/routing
app.URL("docs.show", "release notes/2026") // /docs/release%20notes/2026Catch broken links
URL panics when no route has the name, or when the number of values doesn't match the route's parameters. A link to a page that doesn't exist is a bug, and the panic shows where it is the first time the code runs, in tests or in development.