Metadata with Fetch in Server Component
Unanswered
jaggi73 posted this in #help-forum
jaggi73OP
I Want to create a metadata object from a
page.tsx. The data is dependent on the response from the fetch API. How can I do that?43 Replies
Giant panda
Search the docs for the dynamic version of the metadata API.
generateMetadata@Giant panda `generateMetadata`
jaggi73OP
this is showing an independent fetch call of metadata. This would mean I need to make the same call twice, one the actual data for the page and one for the metadata?
Isnt that inefficient?
Isnt that inefficient?
@jaggi73 this is showing an independent fetch call of metadata. This would mean I need to make the same call twice, one the actual data for the page and one for the metadata?
Isnt that inefficient?
You can deduplicate it; if you use fetch() that is built in https://nextjs.org/docs/app/building-your-application/data-fetching/caching
jaggi73OP
How can I confirm if its being de-duplicated on the server side?
Depends on how you implement it
jaggi73OP
can you elabborate please?
If you use cache(), just need to console.log inside that cache() to see. There should be only one console.log
If you use fetch(your api), console.log in the api server
If you use fetch(your api), console.log in the api server
@joulev If you use cache(), just need to console.log inside that cache() to see. There should be only one console.log
If you use fetch(your api), console.log in the api server
jaggi73OP
import { type Metadata } from "next";
import {
type TXHashPageProps,
type TransactionProps,
} from "@/utils/types/tx.types";
import { TX } from "@/components/tx";
import { getTransaction } from "@/utils/services/api";
const TXHashPage: React.FC<TXHashPageProps> = async ({
params,
searchParams,
}) => {
const transaction = (await getTransaction(
searchParams.chain_name,
params.tx_hash
)) as TransactionProps;
return <TX {...transaction} />;
};
export default TXHashPage;
export async function generateMetadata({
params,
searchParams,
}: TXHashPageProps): Promise<Metadata> {
const transaction = (await getTransaction(
searchParams.chain_name,
params.tx_hash
)) as TransactionProps;
return {
title: transaction.updated_at,
};
}This is my code, the request is not being de-duplicated here
@joulev how did you implement `getTransaction`
jaggi73OP
export const getTransaction = async (
chain_name: string,
tx_hash: string
): Promise<TransactionProps> => {
const res = await fetch(`${BASE_URL}/transaction`, {
method: "POST",
body: JSON.stringify({
chain_name: chain_name,
tx_hash: tx_hash,
}),
});
return await res.json();
};@jaggi73 tsx
export const getTransaction = async (
chain_name: string,
tx_hash: string
): Promise<TransactionProps> => {
const res = await fetch(`${BASE_URL}/transaction`, {
method: "POST",
body: JSON.stringify({
chain_name: chain_name,
tx_hash: tx_hash,
}),
});
return await res.json();
};
yes looks good. so? why do you know it is not deduplicated
@joulev yes looks good. so? why do you know it is not deduplicated
jaggi73OP
Im getting rhe serverside log twice, sending an ss, just a sec
Yacare Caiman
Does deduplicate mean get the data from cache ??
Yacare Caiman
It looks like a magic
hmm
jaggi73OP
The same call is made twice consecutively
@jaggi73 this is the log
oh, POST requests are not deduplciated automatically
forgot about this
you have to wrap it in cache()
with GET then you have it deduplicated automatically like so
@joulev oh, POST requests are not deduplciated automatically
jaggi73OP
ahh, ive added that
the log is now
the log is now
well they are different requests aren't they
jaggi73OP
Yup, have another question regarding this
different requests are not deduplicated because there was never a duplicate in the first place
jaggi73OP
Whats the flow of these requests
As in, te orignal call is getting de-duped, which is perfect
But why are there two calls here, if im making the api call only once
As in, te orignal call is getting de-duped, which is perfect
But why are there two calls here, if im making the api call only once
@jaggi73 Click to see attachment
looks like you are fetching your own api routes
don't do that
you are fetching localhost:3000/api/transaction, so i'm suggesting that you move the logic of /api/transaction to your server component directly
jaggi73OP
okay
in short, its the same as
The server hasnt started while the call is made so it fails
getStatiProps or getSererSideProps right?The server hasnt started while the call is made so it fails
it didn't fail, as you see it worked in your case, just the log is weird. But yes it will fail during build if you configure your page to be statically rendered
and yes, it is the same as getStaticProps and getServerSideProps
@jaggi73 will it fail if the page is not static?
then the fetch is made at runtime when the server is running, so it does work – but as i explain in the link, that's still bad practice
@jaggi73 Click to see attachment
what happens here looks like you fetch your
/api/v1/transaction which in turn fetches api.coval...; you should instead just fetch api.coval... directly in server componentsjaggi73OP
Got it