Skip to content

Latest commit

 

History

History

vike-react-apollo

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

npm version

vike-react-apollo

Enables your React components to fetch data using Apollo GraphQL.

Note

You also get progressive rendering, fallback upon loading and/or error, and caching.

Installation
Basic usage
withFallback()
<head> tags
How it works
See also


Installation

  1. npm install @apollo/client @apollo/client-react-streaming graphql vike-react-apollo
  2. Extend +config.js:
    // pages/+config.js
    
    import vikeReact from 'vike-react/config'
    import vikeReactApollo from 'vike-react-apollo/config'
    
    export default {
      // ...
      extends: [vikeReact, vikeReactApollo]
    }
  3. Create +ApolloClient.js:
    // +ApolloClient.js
    
    import { ApolloClient, InMemoryCache } from '@apollo/client-react-streaming'
    
    export default (pageContext: PageContext) =>
       new ApolloClient({
         uri: 'https://countries.trevorblades.com',
         cache: new InMemoryCache()
       })

Note

The vike-react-apollo extension requires vike-react.


Basic usage

// Countries.jsx

import { useSuspenseQuery, gql } from '@apollo/client/index.js'

const Countries = () => {
  const { data } = useSuspenseQuery(gql`
    {
      countries {
        code
        name
      }
    }
  `)

  return (
    <ul>
      {data.countries.map((country) => (
        <li key={country.code}>{country.name}</li>
      ))}
    </ul>
  )
}

Note

Even though useSuspenseQuery() is imported from @apollo/client, you need to install vike-react-apollo for it to work. (The useSuspenseQuery() hook requires an HTML stream integration.)


withFallback()

withFallback(Component) // Use default loading fallback (see +Loading)
withFallback(Component, Loading) // Define loading fallback
withFallback(Component, Loading, Error) // Define loading and error fallback
withFallback(Component, undefined, Error) // Define error fallback
// Country.jsx

import { useSuspenseQuery, gql } from '@apollo/client/index.js'
import { withFallback } from 'vike-react-apollo'

const Country = withFallback(
  ({ code }) => {
    const { data } = useSuspenseQuery(
      gql`
        query Country($code: String!) {
          country(code: $code) {
            name
          }
        }
      `,
      {
        variables: {
          code
        }
      }
    )

    return (
      <div>
        Name: <b>{data.country.name}</b>
      </div>
    )
  },
  ({ code }) => <div>Loading country {code}</div>,
  // The props `retry` and `error` are provided by vike-react-apollo
  // Other props, such as `code`, are provied by the parent component
  ({ code, retry, error }) => (
    <div>
      Failed to load country {code}
      <button onClick={() => retry()}>Retry</button>
    </div>
  )
)

+Loading

If you skip the Loading parameter, then a default loading component (provided by vike-react) is used. You can create a custom default loading component:

// pages/+Loading.jsx

export default { component: LoadingComponent }

function LoadingComponent() {
  // Applies on a component-level
  return <div>Loading...</div>
}

Instead of adding a loading fallback to the component, you can set a loading fallback to the page and layouts:

// pages/+Loading.jsx

export default { layout: LoadingLayout }

function LoadingLayout() {
  // Applies to the page and all layouts
  return <div>Loading...</div>
}

Note

The +Loading.layout setting is optional and only relevant when using useSuspenseQuery() without withFallback() or withFallback(Component, false).

withFallback(Component, false) // Don't set any loading fallback
withFallback(Component, undefined) // Use default loading fallback

Manual <Suspense> boundary

Technically speaking:

You can also manually add a <Suspense> boundary at any arbitrary position:

import { Suspense } from 'react'

function SomePageSection() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <SomeDataFetchingComponent />
      <SomeOtherDataFetchingComponent />
    </Suspense>
  )
}

<head> tags

To set tags such as <title> and <meta name="description"> based on fetched data, you can use <Config>, <Head>, and useConfig().

import { useSuspenseQuery } from '@tanstack/react-query'
import { Config } from 'vike-react/Config'
import { Head } from 'vike-react/Head'

function Movies() {
  const query = useSuspenseQuery(gql`
    {
      movies {
        title
      }
    }
  `)
  const movies = query.data
  return (
    <Config title={`${movies.length} Star Wars Movies`} />
    <Head>
      <meta name="description" content={`All ${movies.length} movies from the Star Wars franchise.`} />
    </Head>
    <ul>{
      movies.map(({ title }) => (
        <li>{title}</li>
      ))
    }</ul>
  )
}

How it works

Upon SSR, the component is rendered to HTML and its data loaded on the server-side. On the client side, the component is merely hydrated.

Upon page navigation (and rendering the first page if SSR is disabled), the component is rendered and its data loaded on the client-side.

Note

With vike-react-apollo you fetch data on a component-level instead of using Vike's data() hook which fetches data on a page-level.

Note

Behind the scenes vike-react-apollo integrates Apollo GraphQL into the HTML stream.


See also