nuxt icon indicating copy to clipboard operation
nuxt copied to clipboard

add `addRouteMiddleware` utility from `@nuxt/kit`

Open rchl opened this issue 5 years ago • 13 comments

What problem does this feature solve?

Simplifies adding middlewares from modules.

Currently (assuming that middleware is added programmatically from a module, without user interaction), to add a middleware from a module, one has to: a) add a middleware using either this.addTemplate or this.addPlugin. b) add a plugin using this.addPlugin c) from the plugin added in previous point, one has to import middleware added in point 'a' just to trigger a side effect of it registering itself in nuxt's middleware array

This is how official auth-module does it* at least and I couldn't find an easier way.

So basically we have to add a plugin just so that it can trigger registration of our custom middleware. It would make sense to be able to skip the plugin step and just add a middleware using function exposed in ModuleContainer api (so just something like this.addMiddleware() from a module.

  • https://github.com/nuxt-community/auth-module/blob/abfa084184240b76d7071c20002a5e96821916f9/lib/module/plugin.js

What does the proposed changes look like?

Add this.addMiddleware() function in ModuleContainer API (this object in a module) for having an easy way of adding a middleware without using extra plugin.

This feature request is available on Nuxt community (#c7796)

rchl avatar Sep 22 '18 11:09 rchl

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

stale[bot] avatar Oct 31 '18 17:10 stale[bot]

Totally agree with you. This feature is missing and the lack of documentation require reverse engineering on other module. For the record and to complete your explanations, you can also use a side effect off addPlugin to auto-register you middleware code :

index.js

  this.addPlugin({
    src: path.resolve(__dirname, 'middleware.js'),
    fileName: './middleware.js'
  })

middleware.js

import Middleware from '../../middleware'

Middleware.auth = function ({ req, app }) {
  if (!process.server) {
    return
  }

  // some code
}

Not that much sexy, but that avoid an useless file.

alexbonhomme avatar Nov 05 '18 12:11 alexbonhomme

@alexbonhomme Unfortunately integrating that function isn't as straightforward. 🙈

manniL avatar Nov 05 '18 15:11 manniL

do u guys find a solution ?

wahengchang avatar Jul 01 '19 03:07 wahengchang

@wahengchang for now, import middleware.js from a plugin as @alexbonhomme suggested.

galvez avatar Jul 01 '19 03:07 galvez

Totally agree with you. This feature is missing and the lack of documentation require reverse engineering on other module. For the record and to complete your explanations, you can also use a side effect off addPlugin to auto-register you middleware code :

index.js

  this.addPlugin({
    src: path.resolve(__dirname, 'middleware.js'),
    fileName: './middleware.js'
  })

middleware.js

import Middleware from '../../middleware'

Middleware.auth = function ({ req, app }) {
  if (!process.server) {
    return
  }

  // some code
}

Not that much sexy, but that avoid an useless file.

You also need to add

this.options.router.middleware.push('auth')

...or it wouldn't work

illjah42 avatar Dec 20 '19 06:12 illjah42

My solution is

this.nuxt.hook('build:templates', ({ templateVars }) => {

  templateVars.middleware.push({
    name: 'middleware-name',
    src: 'middleware-name.js',
    dst: 'path-relative-to-nuxt-folder'
  })

  templateVars.router.middleware.push('middleware-name')
})

digitorum avatar Mar 15 '21 11:03 digitorum

I know this is an older issue but just wanted to add a comment and say it's still a pain point. Myself and my team have hit this within the first month us using Nuxt for a production project. Lost a couple days fighting it before finding this.

code-ape avatar Dec 13 '21 18:12 code-ape

still no solution, tried to move middleware out for sharing purposes, the previous solutions just hangs the app.

pencilcheck avatar Aug 08 '22 09:08 pencilcheck

My solution is

this.nuxt.hook('build:templates', ({ templateVars }) => {

  templateVars.middleware.push({
    name: 'middleware-name',
    src: 'middleware-name.js',
    dst: 'path-relative-to-nuxt-folder'
  })

  templateVars.router.middleware.push('middleware-name')
})

what is "dst"??

pencilcheck avatar Aug 08 '22 09:08 pencilcheck

  this.nuxt.hook('build:templates', ({ templateVars }) => {
    // TODO generate list dynamically
    templateVars.middleware.push({
      name: 'authenticated',
      src: 'middleware/authenticated.js',
      // relative to the build (a.k.a. .nuxt) of the package building it
      dst: relativeTo(
        this.options.buildDir,
        path.resolve(__dirname, 'middleware', 'authenticated.js'),
      )
    })

    // no need for this, including this will cause infinite loop
    //templateVars.router.middleware.push('authenticated')
  })

Figured it out, dst is the path used to generate middleware.js inside .nuxt folder (the build dir), so it has to be relative to the build dir of the project pulling the dependent middleware else where.

pencilcheck avatar Aug 08 '22 10:08 pencilcheck

@pencilcheck what's relativeTo function definition?

FloryanFilip avatar Aug 11 '22 09:08 FloryanFilip

@pencilcheck @digitorum Thanks, it helped us a lot ! Love to see a more straight forward solution like addMiddleware()

@FloryanFilip You can use path.relative

ymenard-aramis avatar Sep 08 '22 10:09 ymenard-aramis

Hello guys, I know this issue was closed, but mayby is util for someone.

This is the code in my module.ts

 this.nuxt.hook("build:templates", ({ templateVars }) => {
    const configuredDir = this.nuxt.options.dir.middleware;
    const extRE = /\.(js|ts)$/;

    const middleware = globSync(`${configuredDir}/*.{js,ts}`, {
      cwd: __dirname,
    });

    templateVars.middleware = middleware.map((src) => {
      src = src.replace(`${configuredDir}/`, "");
      const name = src.replace(extRE, "");
      const dst = path.join(__dirname, `./${configuredDir}`, src);

      consola.warn(`Overwritten middleware: ${name}`);

      return { name, src, dst };
    });
  });

damianpumar avatar Jan 26 '24 15:01 damianpumar