I'm new to Nextjs and have some questions about client-side rendering and server-side rendering in Nextjs
useQuery
hook but only callable on React component function. Does it mean that it only running when rendering the page from the client-sideapolloClient
to Nextjs. It said thatalways create a new instance of
apolloClient
for SSR and only create one instance ofapolloClient
for CSR
Here is the example code
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient();
// If your page has Next.js data fetching methods that use Apollo Client,
// the initial state gets hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract();
// Restore the cache using the data passed from
// getStaticProps/getServerSideProps combined with the existing cached data
_apolloClient.cache.restore({ ...existingCache, ...initialState });
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === "undefined") return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
Can anyone explain that? I'm sorry if the question are silly
Apollo Client provides a handy API for using it with server-side rendering, including a function that executes all of the GraphQL queries that are required to render your component tree. You don't need to make any changes to your queries to support this API.
Next. js has two forms of pre-rendering: Static Generation and Server-side Rendering.
Next. js is used for server side rendering of react application . React along with other framework like angular and vue. js are traditional client side framework ,they run in browser but there are technology to run this framework on server side, and next.
A GraphQL server is a server-side implementation of the GraphQL spec. In other words, a GraphQL server exposes your data as a GraphQL API that your client applications can query for data. These clients could be a single page application, a CMS like Drupal, a mobile app, or almost anything.
The most common use case for server-side rendering is to handle the initial render when a user (or search engine crawler) first requests our app. When the server receives the request, it renders the required component (s) into an HTML string, and then sends it as a response to the client.
It renders the JavaScript and fills the content into it. Server-side rendering, on the other hand, renders the React components on the server. The output is HTML content.
What’s the difference between client-side rendering and server-side rendering? In Client-side rendering, your browser downloads a minimal HTML page. It renders the JavaScript and fills the content into it. Server-side rendering, on the other hand, renders the React components on the server.
Redux's only job on the server side is to provide the initial state of our app. In the following recipe, we are going to look at how to set up server-side rendering. We'll use the simplistic Counter app as a guide and show how the server can render state ahead of time based on the request.
In Next JS:
getServerSideProps
getStaticPaths
& getStaticProps
It is important to note that SSG functions are run server-side.
On the client, you only want to create a single global instance of Apollo Client. Creating multiple instances of Apollo Client will make it challenging to keep things in sync with the client. This difficulty is because the Apollo Cache, Apollo Link, etc., will all be stored in different instances of Apollo Client.
In Next, it is common to place the global instance of Apollo Client on the page _app.js
and use the Apollo Provider. On the other client-side pages, you'd use the useQuery
hook that calls your single global instance.
The server-side (SSR) functions getStaticProps
or getServerSideProps
do not have access to the client instance of Apollo, client instance of Next, or other server-side functions. Because of this, you must define your Apollo connection on every page that uses getStaticPaths
, getStaticProps
, or getServerSideProps
and needs access to the Apollo client or it will not be available to the server-side calls.
Since the first rule of hooks is that they must only be called at the top level (client-side), you cannot use them in server-side functions. No, you cannot run useQuery
in the Next SSR or SSG functions.
The example you provide is keeping the cache in sync and is outdated in how it is defining the client. Here is a simplified example more along the lines of the official docs.
graphqlClient.js
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
// Used server and client side - can't use react hooks
export const graphqlClient = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: 'YOUR_GQL_ENDPOINT',
}),
ssrMode: typeof window === 'undefined',
});
_app.js - a single instance that all client pages use because it wraps the whole app
import graphqlClient from 'my/path/graphqlClient';
const App = ({ Component, pageProps }) => {
const client = graphqlClient();
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
);
};
Every page/component that is client-side that can use the useQuery hook because Apollo Client is wrapping the app in _app.js
Client-side query
import { gql, useQuery } from '@apollo/client';
const About = () => {
const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
return (
...
)
}
Every page that uses SSR or SSG functions and needs access to Apollo must instantiate a new instance of Apollo.
SSG
import graphqlClient from 'my/path/graphqlClient';
//does not have access to _app.js or client and must define new Apollo Client instance
export const getStaticProps = async () => {
const client = graphqlClient();//
const { data } = await client.query({query: YOUR_QUERY});
};
export const getStaticPaths = async () => {
const client = graphqlClient();
const { data } = await client.query({query: YOUR_QUERY});
};
SSR
import graphqlClient from 'my/path/graphqlClient';
//does not have access to _app.js or client and must define new Apollo Client instance
export const getServerSideProps = async () => {
const client = graphqlClient();
const { data } = await client.query({query: YOUR_QUERY});
};
Lastly, to simplify things you can use graphql-code-generator to auto-generate Apollo query, mutation, etc. hooks (and types for TS users) as well as server-side compatible query and mutation functions for Next.js.
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