nuxt / rfcs

RFCs for changes to Nuxt.js
99 stars 2 forks source link

Middleware options to run only on server or client #28

Open Austio opened 5 years ago

Austio commented 5 years ago

TLDR

I would like to implement some way for middleware to be ran in the context of server/client/isomorphic on a per middleware basis.

Problem

Example Playground with Router, Layout and Page middleware

At the moment we are able to control how middleware are applied on a global basis using the mode of either ssr or universal.

Mode Application of middleware
ssr Runs middleware on client page boot and each page transition
universal Runs middleware on server render and each page transition

What this means it that if i have something like a middleware that should only run on the client pages but I am running in universal mode I don't have the option to use the middleware system completely for my concern.

Proposed API

Current middleware would continue to work as is in the way above.

I propose adding annotations to middleware similar to how we handle plugins.

/middleware
  /middleware.client.js 
  /middleware.server.js

This would allow me as a developer who has specific needs to tell nuxt which contexts i would like to run my middleware in without affecting the current implementation in any way.

I would expect these annotations to work in this way.

Middleware File Name Application of middleware
*.client.js Runs middleware on client page boot and each page transition
*.server.js Runs middleware on server render only
*.js Fallback runs in the way that it always had with using the mode to determine application

I am totally open to implement this feature if it is desirable.

Updates

galvez commented 5 years ago

Thanks for the proposal @Austio -- I'm not opposed to it, except there should be no isomorphic.js suffix to follow the standard adopted by plugin definitions (client.js and server.js or none for universal). Nuxt 3 is undergoing some architectural changes which might already cover this usage so I'll let @pi0, @Atinux and @clarkdo chime in when they can.

manniL commented 5 years ago

A way to always run middleware on client-side, even on the first request which is rendered server-side would be great, but I'm not sure if it's possible w/ the current architecture without changing the order. However, this is just a side note, haven't looked into it :relaxed:

pi0 commented 5 years ago

Nice idea. Two points:

rchl commented 5 years ago

There is currently bug in nuxt-i18n (https://github.com/nuxt-community/nuxt-i18n/issues/378) that is due to middleware not running on initial request with mode: universal + nuxt generate.

Since that middleware has handling for both server and client, I don't see how to fix that using this solution. I would need the behavior for initial request to be:

So to fix that case, I would need only that one case to change and I don't see how to fix that using this proposal.

(I can fix it in different way probably, but that's besides the point)

weotch commented 2 years ago

To make a page middleware only run on the client, I followed the advice of this post and used a serverMiddleware to force spa on those pages.

In my case, I want my /account pages to always behave in SPA mode.

// middlewares/client-only-pages.js
export default function (req, res, next) {
    if (req.url.match(/^\/account/)) {
        res.spa = true
    }
    next()
}