To be specific I am showing data on the navbar from the API endpoint. And I want to use getStaticProps to get those data on all the pages. But the problem is I need to do getStaticProps on all the pages.
Can we do something like this and get data on all the pages as props?
//pages/_app.js
function MyApp({ Component, pageProps, navs }) {
return (
<>
<Component {...pageProps} navs={navs} />
</>
);
}
export async function getStaticProps() {
const res = await api.get("/api/v1/navs");
const navs = res.data;
return {
props: {
navs,
},
// revalidate: 60, // In seconds
};
}
export default MyApp;
What could be the alternative way of doing this? Is there a way to manage a global state, so that it is used by all the pages? I don't think we can use Context API to provide data to all the pages too.
This means that instead of fetching an API route from getStaticProps (that itself fetches data from an external source), you can write the server-side code directly in getStaticProps . Take the following example. An API route is used to fetch some data from a CMS.
getServerSideProps does not work in _app. js . see docs. you could use the older getInitialProps in your custom app component but then the automatic static optimisation is disabled, which is something Next.
getStaticProps: It's an async function that we export from the page component, used to generate data on the build time. It fetches the data and generates the HTML pages on our server and it caches it.
You can achieve this by just switching the function getStaticProps to getServerSideProps . The entire function will execute on the server and your redirection will happen. e.g.
NextJS doesn't currently support lifecycle methods in _app.js
.
Since the above isn't supported yet, you'll want to create a reusable getStaticProps
function and export it from all pages. Unfortunately, this does mean some WET code; however, you can reduce some boilerplate by creating a HOC which wraps the page and also exports a getStaticProps function.
You can use getInitialProps
within the _app.js
file. Unfortunately, this disables automatic static optimization across the entire application.
components/Navigation
import * as React from "react";
import Link from "next/link";
import { nav, navItem } from "./Navigation.module.css";
const Navigation = () => (
<div className={nav}>
{[
{ title: "Home", url: "/" },
{ title: "About", url: "/about" },
{ title: "Help", url: "/help" }
].map(({ title, url }) => (
<div className={navItem} key={title}>
<Link href={url}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a>{title}</a>
</Link>
</div>
))}
</div>
);
export default Navigation;
components/UsersList
import * as React from "react";
import isEmpty from "lodash.isempty";
import { noUsers, title, userList, user } from "./UsersList.module.css";
const UsersList = ({ error, users, retrieved }) =>
!retrieved ? (
<p>Loading...</p>
) : !isEmpty(users) ? (
<div className={userList}>
<h1 className={title}>Statically Optimized User List</h1>
{users.map(({ name }) => (
<div className={user} key={name}>
{name}
</div>
))}
</div>
) : (
<div className={noUsers}>{error || "Failed to load users list"}</div>
);
export default UsersList;
containers/withUsersList
import * as React from "react";
import axios from "axios";
import UsersList from "../../components/UsersList";
/**
* A HOC that wraps a page and adds the UserList component to it.
*
* @function withUsersList
* @param Component - a React component (page)
* @returns {ReactElement}
* @example withUsersList(Component)
*/
const withUsersList = (Component) => {
const wrappedComponent = (props) => (
<>
<UsersList {...props} />
<Component {...props} />
</>
);
return wrappedComponent;
};
export const getStaticProps = async () => {
try {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
return {
props: {
retrieved: true,
users: res.data,
error: ""
}
};
} catch (error) {
return {
props: {
retrieved: true,
users: [],
error: error.toString()
}
};
}
};
export default withUsersList;
pages/_app.js
import * as React from "react";
import Navigation from "../components/Navigation";
const App = ({ Component, pageProps }) => (
<>
<Navigation />
<Component {...pageProps} />
</>
);
export default App;
pages/about
import withUsersList, { getStaticProps } from "../containers/withUsersList";
const AboutPage = () => <div>About Us.</div>;
export { getStaticProps };
export default withUsersList(AboutPage);
pages/help
import withUsersList, { getStaticProps } from "../containers/withUsersList";
const HelpPage = () => <div>Find Help Here.</div>;
export { getStaticProps };
export default withUsersList(HelpPage);
pages/index
import withUsersList, { getStaticProps } from "../containers/withUsersList";
const IndexPage = () => <div>Hello World.</div>;
export { getStaticProps };
export default withUsersList(IndexPage);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With