Skip to content

victorgarciaesgi/vite-plugin-typed-router

Repository files navigation

πŸš—πŸš¦ vite-plugin-typed-router

npm version npm downloads npm downloads

Provide a type safe router to any app with auto-generated typed definitions for route names and autocompletion for route params

Support for now:

Framework Support
Vue βœ…
React ❌
Svelte ❌

Features for Vue

  • πŸ”Ί Uses Nuxt 3 file base routing
  • 🏎 Provides a useTypedRouter composable that returns the typed router and an object containing a tree of your routes
  • 🚦 Provides auto-completion and strict typing for route params in push and replace methods

Installation

pnpm i -D vite-plugin-typed-router vue-router
# or
npm install -D vite-plugin-typed-router vue-router

Configuration

First, register the module in the vite.config.ts

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import TypedRouter from 'vite-plugin-typed-router';

export default defineConfig({
  plugins: [vue(), TypedRouter(/* Options */)],
});

In your main.ts, register the routes

import { createApp } from 'vue';
import App from './App.vue';

import { createRouter, createWebHistory } from 'vue-router';
// Generated routes
import routes from '~pages';

const router = createRouter({
  history: createWebHistory(),
  routes,
});

const app = createApp(App);

app.use(router);
app.mount('#app');

Options:

export interface TypedRouterOptions {
  /** Location of your src directory
   * @default "src"
   */
  srcDir?: string;
  /** Output directory where you cant the files to be saved (ex: "./generated")
   * @default "<srcDir>/generated"
   */
  outDir?: string;
  /** Location of your pages directory
   * @default "<srcDir>/pages"
   */
  pagesDir?: string;
  /** Print the generated routes tree object in output
   * @default "true"
   */
  printRoutesTree?: boolean;
}

Generated files

The module will generate 4 files each time you modify the pages folder :

  • ~/<outDir>/__routes.ts with the global object of the route names inside.
  • ~/<outDir>/__useTypedRouter.ts Composable tu simply access your typed routes
  • ~/<outDir>/typed-router.d.ts containing the global typecript definitions and exports

Usage in Vue/Nuxt


Requirements

You can specify the output dir of the generated files in your configuration. It defaults to <srcDir>/generated

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import TypedRouter from 'vite-plugin-typed-router';

export default defineConfig({
  plugins: [vue(), TypedRouter({outDir: 'generated'})],
});

How it works

Given this structure

    β”œβ”€β”€ pages
        β”œβ”€β”€ index
            β”œβ”€β”€ content
                β”œβ”€β”€ [id].vue
            β”œβ”€β”€ content.vue
            β”œβ”€β”€ index.vue
            β”œβ”€β”€ communication.vue
            β”œβ”€β”€ statistics.vue
            β”œβ”€β”€ [user].vue
        β”œβ”€β”€ index.vue
        β”œβ”€β”€ forgotpassword.vue
        β”œβ”€β”€ reset-password.vue
    β”‚   └── login.vue
    └── ...

The generated route list will look like this

export const routesNames = {
  forgotpassword: 'forgotpassword' as const,
  login: 'login' as const,
  resetPassword: 'reset-password' as const,
  index: {
    index: 'index' as const,
    communication: 'index-communication' as const,
    content: {
      id: 'index-content-id' as const,
    },
    statistics: 'index-statistics' as const,
    user: 'index-user' as const,
  },
};
export type TypedRouteList =
  | 'forgotpassword'
  | 'login'
  | 'reset-password'
  | 'index'
  | 'index-communication'
  | 'index-content-id'
  | 'index-statistics'
  | 'index-user';

You can disable routesNames object generation if you don't need it with the printRoutesTree option

Usage with useTypedRouter hook

useTypedRouter is an exported composable from nuxt-typed-router. It contains a clone of vue-router but with strictly typed route names and params type-check

<script lang="ts">
// The path here is `~/generated` because I set `outDir: './generated'` in my module options
import { useTypedRouter } from '~/generated';

export default defineComponent({
  setup() {
    // Fully typed
    const { router, routes } = useTypedRouter();

    function navigate() {
      // Autocompletes the name and infer the params
      router.push({ name: routes.index.user, params: { user: 1 } }); // βœ… valid
      router.push({ name: routes.index.user, params: { foo: 1 } }); // ❌ invalid

      router.push({ name: 'index-user', params: { user: 1 } }); // βœ… valid
      router.push({ name: 'index-user', params: { foo: 1 } }); // ❌ invalid
      router.push({ name: 'index-foo-bar' }); // ❌ invalid
    }

    return { navigate };
  },
});
</script>

About

πŸš—πŸš¦ Provide autocompletion for pages route names and params in Vite apps

Resources

License

Stars

Watchers

Forks

Packages

No packages published