Documentation
Server-Side rendering

Server-Side Rendering

Server-side rendering (SSR) is a popular technique for rendering web pages on the server. This is in contrast to client-side rendering (CSR), where the web page is rendered on the client's browser. SSR is a great way to improve performance and SEO, but it can be challenging to set up and maintain.

Overview

In kickass-toolkit we recommend using Next.js (opens in a new tab) for SSR. Next.js is a framework for building server-rendered React applications. It provides a number of features out of the box. The examples in this page use Next.js, but the concepts apply to any SSR framework.

Basic example

Even though DataService can be instantiated multiple times, we recommend creating a single instance and sharing it across the application during SSR.

We will use RestDataService as an example same as before.

dataService.ts
import { RestDataService } from '@kickass-coderz/data-service'
 
const dataService = new RestDataService()
 
export { dataService }

Now we can import the dataService instance in our pages and use it to fetch data.

pages/index.tsx
import { dataService } from './dataService'
 
const Page = ({ data }) => {
    return (
        <ul>
            {data.map(item => {
                return <li>{item.name}</li>
            })}
        </ul>
    )
}
 
const getServerSideProps = () => {
    // this calls https://api.punkapi.com/v2/beers
    const { data: beers } = await dataService.getList('beers')
 
    return {
        props: {
            beers
        }
    }
}

You can read more about SSR in Next.js here (opens in a new tab).

Using Hydrate

As we use react-query under the hood we can use QueryClient to fetch data on the server with our DataService and then send it to the client to be used inside our hooks like useGetList.

šŸ’”

Make sure you have your DataService setup. If not check our Project setup.

pages/index.tsx
import { dataService } from './dataService'
import { QueryClient, dehydrate } from '@tanstack/react-query'
import { useGetList } from '@kickass-coderz/data-service'
 
const Page = () => {
    const { data } = useGetList({
        resource: 'beers'
    })
 
    return (
        <ul>
            {data.map(item => {
                return <li>{item.name}</li>
            })}
        </ul>
    )
}
 
const getServerSideProps = () => {
    const queryClient = new QueryClient()
 
    await queryClient.prefetchQuery(createGetListQueryKey('beers'), () => dataService.getList('beers'))
 
    return {
        props: {
            beers: dehydrate(queryClient)
        }
    }
}

To use react-query hydration you need to add Hydrate component to your _app.js or _app.tsx file.

const MyApp = ({ Component, pageProps }: AppProps) => {
    return (
        <>
            <Head>
                <title>My Next App</title>
            </Head>
            <DataServiceProvider dataService={dataService}>
                <Hydrate state={pageProps.dehydratedState}>
                    <Component {...pageProps} />
                </Hydrate>
            </DataServiceProvider>
        </>
    )
}

You can learn more about Hydrate component here (opens in a new tab).

By using createGetListQueryKey on server our data is automatically populated inside useGetList hook on the client. This is because with shared query keys useGetList hook automatically knows where to look for list data.

Next.js 13

Next.js introduced new concept of server components as an alternative to data fetching methods. You can read more about it here (opens in a new tab).

Example below shows you how to use DataService with server components.

pages/index.tsx
import { dataService } from './dataService'
 
const Page = async () => {
    // this calls https://api.punkapi.com/v2/beers
    const { data: beers } = await dataService.getList('beers')
 
    return (
        <ul>
            {data.map(item => {
                return <li>{item.name}</li>
            })}
        </ul>
    )
}

With server components being async we can fetch data directly inside of them. We also do not need to use hooks since everything is fetched and rendered on the server exclusively.

In the future we plan to add even more support and features for server components as they become stable.

We recommend using server components but you can however stiil use our hooks inside client components. You can learn more about the differences here (opens in a new tab).