#Pass data from middleware to pages
83 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize
✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)
It is possible, however, doing that also leaks the values to client
It would be best to make a function on top of the route handler to pass the data
#discussions message
you mean by adding the values to the response headers?
yes, but it also leaks it to client
its best to make a function on top of the route handler to pass the values
It doesn't seem to leak if I do the following:
const newHeaders = new Headers(request.headers);
newHeaders.set('user', JSON.stringify(user));
return NextResponse.next({ request: { headers: newHeaders } });
... but it looks hackish...
At the same time I don't understand what's the other solution you are suggesting.
If you check client headers it’s getting leaked
I’ve tried this
I should get it in Response headers in the browser, but right now I'm not getting it..
In postman I was able to view the headers
I’ll show you an screenshot on postman
are you sure you were enriching the passed request headers and not the response headers?
because I tried that before and that actually leaked
Wait, I'll get additional info and I'll answer this question after tomorrow!
super! thx
in the meantime, my screeshot where the value is used in a page.tsx but doesn't appear in the response headers
generally speaking, headers should only be values that a client provides
I agree, in fact I don't like this approach. But I also don't like having to do the same task in both middleware and pages
and I find strange there's no easy way to pass something from middleware to pages/routes, but probably I am not fully understanding the full request/response lifecycle in Next
It’s best to create a function on top of the route handler
can you explain it or point me to some example, because I don't understand what you mean with that?
I’ll do when I get time
@shell wraith check this #discussions message
/**
* Handles POST requests by parsing the request body and validating it against a schema.
* @param handler - The handler function to be executed if the request body is valid.
* @param schema - The schema to validate the request body against.
* @returns A response after executing the function.
*/
export function routePostHandler<T>( schema: ZodSchema<T>, handler: (request: NextRequest, body : T) => Promise<NextResponse | void>) {
return async (request: NextRequest) => {
let body: T;
try {
body = await request.json();
} catch (error) {
return NextResponse.json({message: "Invalid JSON in request body"}, {status: 400});
}
const parsed = schema.safeParse(body);
if (!parsed.success) {
return NextResponse.json({message: "Invalid request body", errors: parsed.error.issues}, {status: 400});
}
const data = await handler(request, parsed.data);
return data || NextResponse.json({message: "Internal Server Error"}, {status: 500});
};
Check this, in this, its checking if type is valid. A functionality for passing data can be added into it
And it can be used in handler like this
export const POST = routePostHandler<Body>(BodySchema, async (req: NextRequest, body: Body) => {
thanks very much for the effort, but I think it doesn't solve my use case
my scenario is the following: suppose I'm using middleware to handle db based authentication (ie: in middleware I access the db to get the user, if no user no auth). I would like to have the user available in subsequent routes/pages without the need to access the db again to retrieve it, given I already did it in the middleware. The approach above doesn't seem to solve this issue, if I am not missing something.
You can do the authentication in higher up function
You can add it here
so you mean not using middleware for auth but delegating to the routes/pages?
that would be a solution, probably
I don't particularly like it, given there is a centralized place where this could be handled (ie: middleware), but it would work
It’s not the best to use middleware for passing data
ok, thank you
If your issue is resolved, mark this message as a solution
@lean belfry Though I'm thankful for your time and effort, I don't consider it to be a valid answer to my question. The code you provided is a factory function (a HOF, to be more specific), that allows you to standardize the creation of route handlers, but doesn't in any way respond to the initial question of avoiding to perform an operation that has already been performed in the middleware. If that was the approach, a simpler solution, without recurring to HOFs (though maybe more elegant), would be to just extract a function that gets the user from db, in my example, and then use/call it in both routes and in pages (also note that the solution you propose is not applicable to pages).
Would you agree with me that having to hit the db multiple times for rendering a page, if I already hit it once for the same data during the page rendering pipeline, doesn't seem an optimal approach? As I probably wrote above, I'm coming from an Express background, and I think Express is the library that popularized the concept of middleware in the JS world, but don't quote me on that. In Express land it is/was a common pattern to enrich the request object with data collected in the middleware chain. So, for example, if I had a requireAuth middleware, I could safely expect to find the user in the request in a subsequent middleware or route handler, which makes a lot of sense to me. I probably don't know a lot of the magic that goes on behind the scenes in Next.js but I'd like to have an answer to my original question, which I don't seem to be able to find anywhere online.
You can wait for an answer then!
🙏
Pass data from middleware to pages
Bump(for him, as I also need a answer)
Bump(for him, as I also need a answer)
@lean belfry I have not had time to find an answer to this yet, but using React's cache (import { cache } from "react") seems to be an interesting path to investigate (https://youtu.be/N_sUsq_y10U?si=utUC4JCr0ysu6mn-&t=412). It sounds an interesting point to evaluate also in another use-case I have enountered, where I needed the same db data both in a Layout and in its child Page
Best practices for authentication in Modern Next.js and React: Server Components, Server Actions, Middleware.
Docs: https://rc.nextjs.org/docs/app/building-your-application/authentication
Code: https://github.com/vercel-labs/app-router-auth
00:00 Intro
00:25 Forms and Server Actions
00:51 Form validation
01:06 useActionState
01:45 Creating a u...
I’ll check it out soon
This video will solve your pro @lean belfry
@shell wraith Were you able to find a method that works?
What's your usecase you need help with?
Probably make another post, this one is already greater than 50 messages and hence isn't very helpful for any future reference
Even I have no clue wtf is going on above lol
I'm currently working on the dashboard and I plan on checking if the user is currently logged in, I'm able to do so properly and redirect them if not, but the library I'm using returns data that can be needed throughout and instead of having to refetch the data I was hoping to just pass it to the page from the middleware
I intended to use unstable_cache but it's unstable & I had an error using it with my library
I would create another one but I noticed that a majority of posts like this just get ignored so I figure why not ask 😅
Issue is, middleware isn't meant to be used for heavy tasks
Essentially the middleware runs on every single request
And that's gonna slow your site down
A shit ton
This is coming from the nextjs devs
Maybe sense, would it be better to redirect the user on the server component instead of the middleware?
The thing we do, is in the middleware just check for the cookie existing, that's it. A quick check. Then in any page which needs auth data you just have a function wrapped in unstable cache and react cache
Which you can call
Unstable cache will cache the request itself, react cache will make sure the data is cached through render passes so only one request is made
Interesting, okay. I'll do that instead. If I decided to use react cache how can I reset it?
For example, I don't think I'll need to ever revalidate the data, but say they change their name or profile picture
You can't like reset it since it's main thing is to make sure if you call a function in multiple components, it's only called once and the rest use that
I seen revalidateTag or something but not sure I can set tags with react cache
How would you go about revalidating the data if they change their username for example?
Router.refresh() would just work with a revalidate to the unstable cache tag
React cache isn't "cache" per say, it just memorizes requests
Yes ik it's a dumb thing
Yeahh I was gonna use unstable cache, but throughout I had this error:
Or even better
So I need to find an alternative
#discussions message
Access cookies outside of the unstable cache
I can't
unless I create a new supabase client
Should I make a new channel for this?
Yea