nuxt-typed-router icon indicating copy to clipboard operation
nuxt-typed-router copied to clipboard

🚦Provide autocompletion and typecheck to Nuxt router

πŸš—πŸš¦ Typed Router for Nuxt

npm version npm downloads npm downloads

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

  • 🏎 Provides a hook useTypedRouter that returns an alias of $typedRouter and also a typed list of your routes
  • 🚚 Expose a global method $typedRouter (clone of vue-router), but typed with the routes defined in pages directory
  • 🚦 Provides auto-completion and errors for route params in push and replace methods

Demo πŸ§ͺ : nuxt-typed-router-demo

Compatibility:



Installation

For Nuxt 3

yarn add -D nuxt-typed-router
# or
npm install -D nuxt-typed-router

For Nuxt 2

For Nuxt 2 usage, check out the docs at the nuxt2 branch

yarn add -D nuxt-typed-router@legacy
# or
npm install -D nuxt-typed-router@legacy

Configuration

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

import TypedRouter from 'nuxt-typed-router';

export default defineNuxtConfig({
  buildModules: [TypedRouter],
  nuxtTypedRouter: {
    // options
  },
});

Options:

interface ModuleOptions {
  /** Output directory where you cant the files to be saved
   * (ex: "./models")
   * @default "<srcDir>/generated"
   */
  outDir?: string;
  /** Name of the routesNames object (ex: "routesTree")
   * @default "routerPagesNames"
   * */
  routesObjectName?: string;
}

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 to simply access your typed routes
  • ~/<outDir>/typed-router.d.ts containing the global typecript definitions and exports
  • ~/plugins/__typed_router.ts Plugin that will inject $typedRouter and $routesList (@nuxt/kit has problems registering plugin templates so this is a workaround)

Usage in Vue/Nuxt


Requirements

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

import TypedRouter from 'nuxt-typed-router';

export default defineNuxtConfig({
  buildModules: [TypedRouter],
  nuxtTypedRouter: {
    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 routerPagesNames = {
  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';

nuxt-typed-router will also create a plugin in your <srcDir>/plugins folder with the injected $typedRouter and $routesList helpers

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
    }

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

Usage with $typedRouter and $routesList injected helpers

$typedRouter is an injected clone of vue-router $router, but fully typed with all your routes. It's available anywhere you have access to Nuxt context

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Index',
  setup() {
    const { $typedRouter, $routesList } = useNuxtApp();

    function navigate() {
      $typedRouter.push({ name: $routesList.activate });
    }

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

Usage outside Vue component

You can import the useTypedRouter composable from where it's generated. Exemple with pinia store here

import pinia from 'pinia';
import { useTypedRouter } from '~/generated';

export const useFooStore = defineStore('foo', {
  actions: {
    bar() {
      const { router, routes } = useTypedRouter();
      router.push({ name: routes.index.user, params: { user: 2 } });
    },
  },
});

Development

  1. Clone this repository
  2. Install dependencies using yarn
  3. Build project for local tests yarn build:local
  4. Start dev playground yarn play
  5. Build project for deploy yarn prepack

πŸ“‘ License

MIT License