Next.js Discord

Discord Forum

How to refresh a server component page instantly if a search parameter exists?

Unanswered
Northeast Congo Lion posted this in #help-forum
Open in Discord
Northeast Congo LionOP
I am using nextjs 14 app router. My /purchased-products page needs to be a server component and that is why I don't think I can do this directly on that page.

I am appending a search parameter to my success_url that stripe redirects someone to after they purchase. I am trying to use that search parameter somehow to make sure this page gets refreshed before they land on it to ensure newly purchased products show instantly on the page.

What I have here is not refreshing the page. Am I thinking about this wrong. Are their better ways to do this?

Thank you!

// middleware.ts file
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import type { Database } from 'supabase-db-types';

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();
  const supabase = createMiddlewareClient<Database>({ req, res });
  await supabase.auth.getSession();

  // My attempt to refresh data on specific page after purchases to ensure newly purchased products show instantly. Search param gets added to success_urls in checkout session api route.
  const revalidatePurchasedProductsPage = req.nextUrl.searchParams.get('purchase');
  if (revalidatePurchasedProductsPage === 'yes') {
    revalidatePath('/purchased-products');
    return NextResponse.redirect('/purchased-products'); // additional redirect is needed because revalidatePath will only show new data on next page visit?
  }

  return res;

1 Reply

Northeast Congo LionOP
I think I figured this out.

Instead of middleware, I created an api/revalidate/route.ts to handle this logic and it seems to work for me. I thought middleware would be the spot to handle something like this but looks like I was wrong.

My API Route Example:
// api/revalidate/route.ts file
import { getURL } from '@/utils/helpers';
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const revalidatePurchasedProductsPage = request.nextUrl.searchParams.get('purchase');

  if (revalidatePurchasedProductsPage === 'yes') {
    // 1. First, refresh data on purchase page after purchases to ensure newly purchased products show instantly.
    revalidatePath('/purchased-products');

    // 2. Lastly, redirect to the page we want them to land on after purchase
    return NextResponse.redirect(`${getURL()}/purchased-products`);
  }

  return NextResponse.redirect(`${getURL()}/`); // default redirect location 
}


Then for the success_url in my create checkout session api route for stripe, I set to be the above revalidate api route path + my purchase search param to use in identifying when to revalidate the path.

My Success URL example:
session = await stripe.checkout.sessions.create({
  ....
  ....
  success_url=`${getURL()}/api/revalidate/?purchase=yes`
})


I got the idea for using an api route to revalidate the path from Nextjs documentation. See here:
https://nextjs.org/docs/app/api-reference/functions/revalidatePath#route-handler