Next.js Discord

Discord Forum

Strange behaviour. GET request must be called 2 times.

Unanswered
kubas posted this in #help-forum
Open in Discord
Hi, i have a quick question. Why do I have to send a GET request 2 times to my api to fetch a new list of posts? I send my code:
### API Code:
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const url = new URL(req.url);
  const auth = url.searchParams.get('auth');
  if(!auth) return NextResponse.json({revalidated: false, message: 'NO AUTH ID'}, {status: 400})
  if(auth != process.env.HYGRAPH_WEBHOOK_REVALIDATE_AUTHID) return NextResponse.json({revalidated: false, message: 'INVALID AUTH ID'}, {status: 401})
  revalidateTag('blogFetch')
  return NextResponse.json({revalidated: true, message: 'OK'}, {status: 200})
}

### Page Code:
const Home = async() => {
  const response: { data: { posts: Post[]}} = await fetch(hygraphContentApi, {
    next: {
      tags: ['blogFetch']
    },
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `
        query {
          posts {
            title
            createdAt
            shortDescription
            slug
            author {
              name
              picture {
                url
              }
            }
            coverImage {
              url
            }
          }
        }
      `,
    })
  }).then(res => res.json())
  const posts = response.data.posts
  return (
    <main>
      {posts ? (
        <div className={styles.blogCardsContainer}>
        {posts.length > 0 ? (
          posts.map((post) => (
            <BlogCard key={post.slug} post={JSON.stringify(post)} />
          ))
        ) : (
          null 
        )}
        </div>  
      ) : <div className={styles.loading}>Loading...</div>}
    </main>
  );
};

export default Home;
It's really weird weird behavior. I tried if it works normally after doing npm run build and npm run start but nothing changed.

14 Replies

afaik revalidateTag basically makes the cache stale for this specific tag
so the next time you request something that fetches with this tag, it triggers a revalidation on the background
then on the next time you request the same resource, it will give you the updated data
@Rafael Almeida then on the next time you request the same resource, it will give you the updated data
so how can i make one GET request enough for my page to refresh? I tried to do it by revalidateTag('blogFetch') 2 times but it didn't work.
I haven't tested it yet, but I think you need to call revalidateTag then doing a request to the page with fetch, this should trigger the revalidation in the background
ok, i'll try it and let you know
I don't think it works. This is what this code looks like:
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const url = new URL(req.url);
  const auth = url.searchParams.get('auth');
  if(!auth) return NextResponse.json({revalidated: false, message: 'NO AUTH ID'}, {status: 400})
  if(auth != process.env.HYGRAPH_WEBHOOK_REVALIDATE_AUTHID) return NextResponse.json({revalidated: false, message: 'INVALID AUTH ID'}, {status: 401})
  revalidateTag('blogFetch')
  await fetch('http://localhost:3000/blog')
  return NextResponse.json({revalidated: true, message: 'OK'}, {status: 200})
}
Still need to do it 2 times
oh thats a bummer, I was gonna try doing this with my own project
well I don't have a better answer for this atm, I will try later this week to see if I can trigger the rebuild and I can get back to you if I have any success
@Rafael Almeida well I don't have a better answer for this atm, I will try later this week to see if I can trigger the rebuild and I can get back to you if I have any success
Okay, if you find out anything new, you can let me know. I'll try it and let you know if I find out anything.
@Rafael Almeida In theory, I fixed it, but I ran into a problem. On npm run dev it works great, after sending one GET request to my api, everything refreshes, but after npm run build and then npm run start, the page doesn't want to refresh. I can send 100 GET requests to my api and nothing happens. I send the code:
### API CODE:
import { revalidatePath } from "next/cache";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const url = new URL(req.url);
  const auth = url.searchParams.get('auth');
  const path = url.searchParams.get('path')
  if(!path) return NextResponse.json({revalidated: false}, {status: 400})
  if(!auth) return NextResponse.json({revalidated: false}, {status: 400})
  if(auth != process.env.HYGRAPH_WEBHOOK_REVALIDATE_AUTHID) return NextResponse.json({revalidated: false}, {status: 401})
  revalidatePath(path)
  return NextResponse.json({revalidated: true, message: 'OK'}, {status: 200})
}
### My /blog page code:
import BlogCard from '@/components/blog/PostCard';
import styles from './blog.module.scss';

const hygraphContentApi = "valid url hereeeee";

interface Post {
  title: string;
  createdAt: string;
  slug: string;
  shortDescription: string;
  author: {
    name: string;
    picture: {
      url: string;
    };
  };
  coverImage: {
    url: string;
  };
}

const QUERY = `
query {
  posts {
    title
    createdAt
    shortDescription
    slug
    author {
      name
      picture {
        url
      }
    }
    coverImage {
      url
    }
  }
}
`

const Home = async() => {
  const response: { data: { posts: Post[]}} = await fetch(hygraphContentApi, {
    
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: QUERY,
    })
  }).then(res => res.json())
  const posts = [...response.data.posts].sort((a, b) => {
    const dateA: Date = new Date(a.createdAt);
    const dateB: Date = new Date(b.createdAt);
    return dateB.getTime() - dateA.getTime();
  });
  return (
    <main>
      {posts ? (
        <div className={styles.blogCardsContainer}>
        {posts.length > 0 ? (
          posts.map((post) => (
            <BlogCard key={post.slug} post={JSON.stringify(post)} />
          ))
        ) : (
          null 
        )}
        </div>  
      ) : <div className={styles.loading}>Loading...</div>}
    </main>
  );
};

export default Home;