Plugin middleware setup in typescript

Hey, Kapa is dead :frowning_with_open_mouth:
I’m trying to add a global middleware to my plugin in typescript but I can’t manage to set it up. I receive 404 response on all requests and console.log('Middleware'); (see under) is never logged

My middleware in src/plugins/myplugin/server/middlewares/redirect.ts

export default () => async (ctx, next) => {
    console.log('Middleware');
    await next();
  };
};

I registered it in `src/plugins/myplugin/server/register.ts``

...
strapi.server.use(middlewares.redirect)

And I also added it to my config/middleware.ts file since it is a global middleware.

export default [
  'strapi::logger',
  'strapi::errors',
  'plugin::myplugin.redirect',
  'strapi::cors',
...

Did I miss something ?
I did not find any documentation for writing middlewares in typescript, nor any example in existing plugins. :grimacing:

This topic has been created from a Discord post (1240319511857463429) to give it more visibility.
It will be on Read-Only mode here.
Join the conversation on Discord

Documentation at Server API for plugins | Strapi Documentation says :

(in js)

'use strict';
module.exports = async (ctx, next) => {
  console.log("your custom logic")
  await next();
}

So I tried to update mine to :

export default async (ctx, next) => {
    console.log('Middleware');
    await next();
  };
};

But I get an error β€œmiddleware must be a function”

Something fishy here

I just found the fix. I’ll post it shortly

yep i’m firing issue but not sure do they ned a doc change or it’s a code

Did you just tested it ?

And think it’s a issue ?

Ok, thanks

Firstly, there was no issue with the config/middleware.ts. The problem was in the plugin.

This does not work:
server/middlewares/redirect.ts

const redirect = async (ctx: any, next: any) => {
  console.log('MyMiddleware');
  await next();
};
export default redirect;

server/middleware/index.ts

import redirect from './redirect';

export default {
  redirect,
};

server/register.ts

import { Strapi } from '@strapi/strapi';
import middleware from './middlewares';

console.log(middleware.redirect) //This is undefined
export default ({ strapi }: { strapi: Strapi }) => {
  strapi.server.use(middleware.redirect); //registration fails
};

middleware.redirect is undefined, registration fails.

However, this is functional:
server/register.ts

import { Strapi } from '@strapi/strapi';

export default ({ strapi }: { strapi: Strapi }) => {
  strapi.server.use(async (ctx: any, next: any) => {
    console.log('MyMiddleware');
    await next();
  });
};

The way I found, which I don’t know why (or more exactly, I don’t understand why the other way does not work):

server/middlewares/redirect.ts

const redirect = () => async (ctx: any, next: any) => { //Redirect is now a function that returns the middleware.
  console.log('MyMiddleware');
  await next();
};
export default redirect;

server/middleware/index.ts

import redirect from './redirect';

export default {
  redirect,
};

server/register.ts

import { Strapi } from '@strapi/strapi';
import middleware from './middlewares';

console.log(middleware.redirect()) //This is not undefined anymore
export default ({ strapi }: { strapi: Strapi }) => {
  strapi.server.use(middleware.redirect()); //I call the function that returns my middleware and that works.
};

Does someone with dark magic experience give an explanation ? :slightly_smiling_face:

PS: If you are reading this to understand how to create your global middleware in typescript, don’t forget to add it to the /config/middleware.ts file !