Sunday, June 16, 2024

Introducing a new router for Vue

Programming LanguageIntroducing a new router for Vue

Brief history of my journey with vue-router

Virtually every developer using Vue.js is currently using or has only ever used vue-router. Many of those developers, myself included, are mostly happy with it. The biggest complaint I hear is the lack of strongly typed routes, which is usually solved with a bit of Typescript wrapping your routes.

// router/routes.ts
import { RouteLocationRaw, RouteRecordRaw } from 'vue-router'

type RouteFunction = (...args: any[]) => RouteLocationRaw

export const routes = {
  home: () => ({ name: 'home' }) as const,
  club: (clubId: string) => ({ name: 'clubs.view', params: { clubId } }) as const,
  profile: (userId?: string) => ({ name: 'profile.view', query: { userId } }) as const,
} satisfies Record<string, RouteFunction>
Enter fullscreen mode

Exit fullscreen mode

Then routes becomes your source of truth, so navigation should always use a route from routes to send proper names to vue-router.

<router-link :to="'club-123')">go to club</router-link>
Enter fullscreen mode

Exit fullscreen mode

The syntax of defining routes is a bit cumbersome but honestly works fairly well. However, because I’m a serial starter-of-new-projects and love a challenge, I teamed up with Pleek91 to see if we could build our own.

It’s intentionally different

We made the decision to start the project from scratch; solving problems from first principles rather than taking the path of so many others and try to build on top of the relatively old vue-router project. This means Kitbag Router is NOT a drop in replacement for projects using vue-router. Therefore, this freedom also means we can have a relentless pursuit of the best possible developer experience possible, not weighed down by having to have feature parity with vue-router.

First and foremost, it’s type safe!

Kitbag Router uses a createRoutes utility that returns routes with the name, path, query, all preserved in the Route type. This means the routes you provide to createRouter will maintain type safety when accessing the current route or performing navigation.

Type safety in routing means auto complete when assigning to on <router-link>, easy discovery of available routes when defining a beforeRouteEnter hook, and ensuring that Typescript will error if the expected params for a route change without updating the router.push() call.

Params are way more powerful

Not only does Kitbag Router know what params are expected for a given route, it can also support param types beyond String.

Kitbag Router ships with built in support for params of typeString, Number, Boolean, Date, RegExp, JSON, as well as any custom param type you define. Not only is this type useful when navigating, but it also means a route that expects a number for an “id” param won’t be considered a match if the value provided in the URL doesn’t satisfy the number constraint. Furthermore, your Vue component that gets rendered for the route doesn’t have to worry about whether the param will be present or not or having to convert it from string to the type we know it’s supposed to be.

Support for the query

Params aren’t relegated to only the path. Kitbag Router allows you to configure your expected params in the query the same way you’re used to defining params in other parts of the URL.

Handling rejections

Inevitably when defining your routes, you’ll want to add a “catch all” or “not found” route. While Kitbag Router fully supports defining plain ol’ Regex in your path/query, it also ships with even better support for handling NotFound. We call this a “rejection”, which is customizable and can be extended to any custom rejection you need, like perhaps NotAuthorized. When a rejection is triggered, usually from within one of your hooks, Kitbag Router will automatically render the rejection component you assigned for the given rejection type.

And more…

These are the key features we think really make Kitbag Router compelling but there is so much more. Kitbag router is built for Vue3 and support async components, route hooks, editable params from useRoute, components for RouterLink and RouterView, and more.

Is it ready?

Kitbag Router is still super green and currently maintained by a team of 2. It has not yet had a stable release (on 0.2.0 as of the time I’m writing this), so things are still likely to change. That being said, I hope you’ll give it a try, maybe give it a star. We’re excited to hear from the community on what features we should focus on next.

Happy engineering!

Check out our other content

Check out other tags:

Most Popular Articles