SSR
Server-side-rendering is supported out-of-the-box. When you set a default
value in useFetch
, it will also be server-side-rendered.
Because fetching with useFetch
doesn't work server-side, you can use the Client
object, which is very similar to Axios
(opens in a new tab) but sends the request using fetch
instead of an XMLHttpRequest
. In case you want to re-use it, it has an extend
property (similar to axios.create
)
Example using Next.js's getServerSideProps
(opens in a new tab):
import useFetch, { Client } from 'http-react'
// It works inside server and client components
const api = Client.extend({
baseUrl: 'https://my-api.com',
headers: {
Authorization: 'Token etc'
}
})
export async function getServerSideProps(context) {
// 'loading' does not work here
const { data } = await api.get('/api/user')
return {
props: {
user: data
} // will be passed to the page component as props
}
}
export default function MyPage({ user }) {
const { data } = useFetch('/api/user', {
default: user
})
return (
<div>
<h2>Welcome, {data.name}</h2>
</div>
)
}
With Server Components in Next.js:
This part covers server-side rendering with Next.js ^13.0.0
(with server components). They work in a differente way from client components. The main difference is that Server components don't ship any JavaScript to the client, thus they are not interactive. This means that things such as useState
or createContext
don't work directly inside them. However, they run server-only code, making them perfect for things like layouts and user authentication. Let's look at an example of data fetching in the server using http-react
:
Inside the main layout (a server component):
import { cookies } from 'next/headers'
import { FetchConfig, Client } from 'http-react'
import Login from 'components/Login'
export default function Layout({ children }) {
// This is only works in server components!
const appSession = cookies().get('appSession')?.value
const baseUrl = 'https://my-website.com/api'
const headers = {
Authorization: 'Token ' + appSession
}
// Creating a client
// (we can't pass a fetcher function because functions can't be serialized!)
const api = Client.extend({
baseUrl,
headers
})
// This works everywhere
const { data, error } = await api.get('/auth')
if (error) return <Login />
return (
<FetchConfig
{...api.config}
value={{
'GET /api/profile': data // This will be SSR!
}}
>
{children}
</FetchConfig>
)
}
Inside pages/profile.tsx
:
'use client' // This marks this component as interactive
import useFetch from 'http-react'
export default function Profile() {
const { data } = useFetch('/api/profile') // Data will be preloaded here!
return (
<div>
<h2>Name: {data.name}</h2>
</div>
)
}
Learn more about -> Server and Client Components (Next.js) (opens in a new tab)