Deduplicate getAccountFull calls in profile page (generateMetadata + prefetch)
Problem
Profile pages (/@username) call getAccountFull() twice during SSR - once in generateMetadata() and once in the layout prefetch. This results in 2 API calls (condenser_api.get_accounts + condenser_api.get_follow_count) that could be deduplicated.
Root Cause
In apps/blog/app/[param]/(user-profile)/layout.tsx:
// generateMetadata() - Line ~45-60
export async function generateMetadata({ params }: ProfileLayoutProps): Promise<Metadata> {
const username = (await params).param.slice(1);
const accountData = await getAccountFull(username); // FIRST CALL
// ... uses accountData for OG metadata
}
// Layout component - Line ~80-96
export default async function ProfileLayout({ children, params }: ProfileLayoutProps) {
const username = resolveParam.param.slice(1);
// ...
await queryClient.prefetchQuery({
queryKey: ['profileData', username],
queryFn: () => getAccountFull(username) // SECOND CALL (same data!)
});
// ...
}
Why React Query Doesn't Deduplicate This
-
generateMetadata()runs before the component renders - It calls
getAccountFull()directly (not through React Query) - The layout then calls
prefetchQuery()with the same function - Since
generateMetadata()doesn't use React Query, the data isn't cached
Impact
-
2 API calls instead of 1 per profile page visit:
condenser_api.get_accountscondenser_api.get_follow_count
- Increases API load unnecessarily
- Adds latency to profile page SSR
Proposed Fix
Use Next.js cache() to deduplicate the function at the request level:
// In a shared utility or at top of layout.tsx
import { cache } from 'react';
const getAccountFullCached = cache(async (username: string) => {
return getAccountFull(username);
});
// Then use getAccountFullCached in both generateMetadata() and prefetchQuery()
Alternative: Only fetch in one place and pass data down, but cache() is cleaner.
Implementation
- Create cached wrapper in
apps/blog/lib/cached-api.ts:
import { cache } from 'react';
import { getAccountFull } from '@transaction/lib/hive-api';
export const getAccountFullCached = cache(getAccountFull);
- Update
layout.tsxto use cached version in both places
Related
- #790 (closed) - Remove unnecessary SSR prefetch for user subscriptions
- #793 (closed) - Remove duplicate community data prefetching
- #764 - Current API calls are sub-optimal for denser needs
- NOTES/05-api-call-comparison-results.md - Full API comparison analysis