#Is there a way to abort streaming in nextjs14 while at generateMetadata stage?

29 messages · Page 1 of 1 (latest)

lone pecan
#

Iam trying to figure out how to use new nextjs with its app router and streaming properly. And a little bit stuck. I have a simple page with a component surrounded by suspense. Component does a request to a throttled endpoint that takes 10 seconds to resolve. Then I'am adding a generateMetadata to the page and call notFound(). Browser immediately shows 404 page with a proper status code - thats okay. And then I expect that client side finishes to do things at that point, but it continues to await that 10s throttled data to stream. I feel that I miss something. Especially when doing curl you need to wait all 10 secs to receive that 404. Is there a way to abort streaming if it is already known at the beginning (metadata) that it will end up with 404 and no more data needs to be sent?

pine aspenBOT
#

🔎 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)

bleak panther
lone pecan
bleak panther
lone pecan
#

i hoped there is something like notFound({ killAll: true })

bleak panther
lone pecan
#

sadly it wont work because abort controller persists

bleak panther
bleak panther
lone pecan
bleak panther
lone pecan
#
const ac = new AbortController();

export async function generateMetadata(
  { params }: { params: {id: string}}
): Promise<Metadata> {
  const { id } = params;

  const result = await fetch1(ac)(id);

  if (!result) {
    ac.abort();
    notFound();
  }

  return {
    title: result.title,
  }
}

export default function Page1({ params }: { params: { id: string } }) {
  const { id } = params;

  return (
    <div className="flex h-screen flex-col">
      <div className="grow">
        <Suspense fallback={<Loader />}>
          <Child1 id={id} ac={ac} />
        </Suspense>
        <Suspense fallback={<Loader />}>
          <Child2 id={id} ac={ac} />
        </Suspense>
      </div>
    </div>
  );
}
#
export default async function Child1({ id, ac }: { id: string, ac: AbortController }) {
  const result = await fetch1(ac)(id);

  if (!result) {
    return notFound();
  }
  
  return (<div>result.title</div>);
}

export default async function Child2({ id, ac }: { id: string, ac: AbortController }) {
  const result = await fetch2(ac)(id);

  if (!result) {
    return (<div>Failed to fetch</div>);
  }
  
  return (<div>result.title</div>);
}
#
export const fetch1 = (abort: AbortController) => async (
  id: string,
): Promise<Rec | null> => {
  try {
    const url = `${process.env.API_URL}/fetch1/${id}`;
    const res = await fetch(url, { cache, signal: abort.signal });
    // some code
  } catch (e) {
    return null;
  }
};

export const fetch2 = (abort: AbortController) => async (
  id: string,
): Promise<Rec | null> => {
  try {
    // THIS ONE TAKES 10s to load for the purpose of experiment
    const url = `${process.env.API_URL}/fetch2/${id}`;
    const res = await fetch(url, { cache, signal: abort.signal });
    // some code
  } catch (e) {
    return null;
  }
};
bleak panther
bleak panther
lone pecan
#
export const fetch1C = cache(fetch1);

right?
and now iam using fetch1C everywhere

lone pecan
#

still same effect, after first invalid id and notFound-abort invocation, all previously opened valid pages become 404, because abortController stays the same on the client side and is already aborted as far as i understand

lone pecan
#

oh thank you, but i dont want you to waste your time on reproducing this, i still believe that there is some pattern exist... or iam using nextjs upside down

bleak panther
lone pecan
#

thats the point!

bleak panther
#

is that what you want?

lone pecan
#

yes! tested - this way now it works as I want! thank you! now i got what was wrong in my understanding of how things should be organized!