Next.js Discord

Discord Forum

Prevent revalidation on server request

Unanswered
American posted this in #help-forum
Open in Discord
AmericanOP
Hi there, I'm trying to make a functionality to refech user data on every page change, but next is always revalidating page when I send a request from the client component with server side request. Any ideas how to prevent it?

82 Replies

Munchkin
You've got to give more context
AmericanOP
Sure, so here is the client component

useEffect(() => {
        (async function check() {
            const request = await laravelSession();

            if (!isGenericApiError(request)) {
                if (session && request.data.user) {
                    if (
                        session.user.avatar !== request.data.user.user?.avatar ||
                        session.user.title !== request.data.user.user.title
                    ) {
                        await update({
                            avatar: request.data.user.user?.avatar,
                            title: request.data.user.user.title,
                        })
                    }
                } else if (!request.data.user && session) {
                    toast.error('Session expired... Logging out')
                    await clientApiRequest().post<any, any>('auth/destroy', {});
                    await signOut()
                }
            }
        })();
    }, [pathname])


and laravelRequest function looks like (it's marked as use server)

export const laravelSession = async () => {
    const header = headers();
    const cookie = cookies();

    const request = await apiRequest().post<any>(
        `auth/session`,
        {client: header}
    );

    if(!isGenericApiError(request) && cookie.get('sessionId') !== request.data.session_id){
        cookie.set('sessionId', request.data.session_id);
    }

    return request
};
export const laravelSession = async () => {
    const header = headers();
    const cookie = cookies();

    const request = await apiRequest().post<any>(
        `auth/session`,
        {client: header}
    );

    if(!isGenericApiError(request) && cookie.get('sessionId') !== request.data.session_id){
        cookie.set('sessionId', request.data.session_id);
    }

    return request
};
is it better now?
I will delete some of the code
I reduced some of the code
Munchkin
Wrap it around that
add js at the beggining now
Great!
AmericanOP
Okay, should be good now
Munchkin
Let me take a look.
AmericanOP
Thanks mate
Munchkin
What do you mean by revalidating page?
AmericanOP
Here is a ss, server-action is making another request here
Munchkin
Yeah; as you may know server-action is experimental. I'm trying to see if there's any mistakes; else it'll be a bug.
AmericanOP
Is it actually making another request or?
Munchkin
You are making two requests. Although they seem different.
It looks like it
Some weird multirendering
I would need to see more to understand
AmericanOP
It's not doing it if I send request to pages/api, but when I try with server action directly to the API it is
Munchkin
Yeah; it's revalidating twice now I see what you mean
AmericanOP
If I remove provided code, it will not make it
Munchkin
Every time it hits the server action; it revalidates the page.
AmericanOP
Yeah... it's pretty annoying
Munchkin
Do you have any revalidate restrictions in place?
like x amount of time, etc?
Can you share your revalidate/product-updates code?
AmericanOP
product-updates is actually a page
so it's a full page in that case, not a request
Munchkin
Ok ... What are you using server action?
Instead of API call? or Middleware?
AmericanOP
Well I have to update session on the client if that request returns some changes
Munchkin
Your API is not Next but in laravel right?
AmericanOP
I could do it from the pages/api and create a request, but I want to prevent that somehow
Munchkin
Yeah, it wouldn't make sence to re-route everything through the API.
AmericanOP
Yes, I also have api for the nextjs doing same thing, so I can fix it, but I want to figure out to do it from the server request
I did it, now when I saw that server actions are fixed, I'm doing some refactoring
Munchkin
How you're handling it; it's not correct. I was doing something like this a few days ago.
Not correct is not the answer, but could be better.
You might want to set the headers straight from the API.
On the response.
AmericanOP
I have fix, I just need to call this

import type {NextApiRequest, NextApiResponse} from 'next';
import {isGenericApiError} from "@/guards/genericApiError";
import {clientRequest} from "@/backend/apiRequest";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
    if (req.method === 'GET') {
        try {
            const createRequest = await clientRequest(req);

            const request = await createRequest.post<any>(`auth/session`, {
                client: req.headers
            }, true);

            if (isGenericApiError(request)) {
                res.status(422).json({
                    message: request.message,
                    errors: request.errors
                });
            } else {
                const setCookieHeader = `sessionId=${request.data.session_id}; Path=/; SameSite=Lax`;

                res.setHeader("Set-Cookie", setCookieHeader)

                res.status(200).json({
                    'data': request.data
                });
            }
        } catch (error: any) {
            res.status(500).json({error: error.message});
        }
    } else {
        res.status(405).json({message: 'Method not allowed'});
    }
};

export default handler;
So this will work as it should
Munchkin
But you would be re-routing yourself unnecessarily.
AmericanOP
Yup
Munchkin
Your laravel response; should set the cookies automatically.
No need to set them on the client.
AmericanOP
How would you do that? Refetch user data on every page change?
Well I'm trying to hide my laravel api as much as possible
that's why I'm rerouting
Munchkin
I have a user token (jwt) which expires every minute and I also have a refresh token which expires in 30 days.
If you want to hide it then make every single call form the next api.
@Munchkin I have a user token (jwt) which expires every minute and I also have a refresh token which expires in 30 days.
Munchkin
I have a middleware post function which checks if the token expired; if it did; i call the API with my refresh token and request a new token.
and then continue with the request
AmericanOP
Well I could do a rewrites in next.config, but still... idea is to send different payload from client to next api, and from next api to the laravel
Munchkin
You don't need to fetch user data every time; just once
AmericanOP
My clients like to explore and hack so 😄
Munchkin
then use Next API as middleware but it'll be like building two API's.
AmericanOP
Yeah and I did it already, so I already have all set for next api as a middleware
Munchkin
then remove your server actions
And use middleware
AmericanOP
Yeah, probabbly will do it like so
I didn't push to prod so I already have finished code
If you are interested you can check it out
Munchkin
Sure, send me the link; 'll take a look.
AmericanOP
Munchkin
It's fast. You did the entire forums on Next? Or just the frontend??
AmericanOP
NextJs with NodeJs and Laravel
that's actually just 15% of the full platform, there is much more of it than forum
Also, it's white-labeled
So I will release NextJs open-source
Munchkin
Well if your users like to hack; I wouldn't recommend it.
They'll find vulnerabilities easier.
AmericanOP
That's why I will ensure before release 😄
I have few of the hackers who olready did the job in past years
so they are testing it
Munchkin
Sounds fun! Good luck.
AmericanOP
Thanks mate! Good luck