Implement a way to get data on Head and Page from a single database query #44639
-
Describe the feature you'd like to requestTo start, I want to thank you for the awesome work. I have been enjoying Next.js 13 a lot and all these amazing features that you bring to us. Experimenting with the new app directory architecture, I found it very hard to get the same data in In the following example, I am trying to get the title of the page for the Right now, this is going to result in two different database queries: Two separate queries to the Database// head.jsx
import { getPageInfoFromDatabase } from '../database/index';
export default async function Head() {
// Database query No. 1
const pageInfo = await getPageInfoFromDatabase();
return (
<>
<title>{pageInfo.title}</title>
<meta name="description" content={pageInfo.description} />
<link rel="icon" href="/favicon.ico" />
</>
);
} // page.jsx
import { getPageInfoFromDatabase } from '../database/index';
export default async function Home() {
// Database query No. 2
const pageInfo = await getPageInfoFromDatabase();
return (
<main>
<h1>{pageInfo.title}</h1>
<p>{pageInfo.data} </p>
</main>
);
} I also created a reproduction example that presents query data directly from the page. In the example, it can be tested how the direct call approach results in multiple function call. https://github.com/Josehower/next-13-data-fetching-demo Describe the solution you'd likeA possible solution would be either:
A possible API for this communication may be this: // layout.jsx
import { getPageInfoFromDatabase } from '../database/index';
export default async function RootLayout({ Head, Page }) {
const pageInfo = await getPageInfoFromDatabase();
return (
<html lang="en">
<Head pageInfo={pageInfo} />
<body>
<Page pageInfo={pageInfo} />
</body>
</html>
);
}
Describe alternatives you've consideredI am aware that Next.js perform a fetch deduping when |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 1 reply
-
The following example would create a single query, but it is not what I would like to have since it adds an HTTP request that I think is unnecessary. Single query to the Database but adds unnecesary HTTP request overhead// head.jsx
export default async function Head() {
const request = await fetch('http://localhost:3000/api/pageInfo');
const pageInfo = await request.json();
return (
<>
<title>{pageInfo.title}</title>
<meta name="description" content={pageInfo.description} />
<link rel="icon" href="/favicon.ico" />
</>
);
} // page.jsx
export default async function Home() {
const request = await fetch('http://localhost:3000/api/pageInfo');
const pageInfo = await request.json();
return (
<main>
<h1>{pageInfo.title}</h1>
<p>{pageInfo.data} </p>
</main>
);
} // pages/api/pageInfo.js
import { getPageInfoFromDatabase } from '../../database';
export default async function handler(req, res) {
const pageInfo = await getPageInfoFromDatabase();
res.status(200).json(pageInfo);
} |
Beta Was this translation helpful? Give feedback.
-
This looks like a cool proposal! 🙌 The passing of props from Also feels like the export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
} |
Beta Was this translation helpful? Give feedback.
-
@sebmarkbage @leerob @timneutkens if these proposals above are not tenable and Vercel has no plans on creating these features, are there any alternative plans on offering some new APIs like
|
Beta Was this translation helpful? Give feedback.
-
You can use import {cache} from "react";
const getPageInfoFromDatabase = cache(function getPageInfoFromDatabase() {
}); |
Beta Was this translation helpful? Give feedback.
-
@balazsorban44 what do you think about also getting feedback on the solution 1 above? Having a way to pass props from |
Beta Was this translation helpful? Give feedback.
You can use
cache
fromreact
to create a function that's deduped.