Skip to content

This is an educational project in Next.js 15 RC + React 19 for my colleagues, which highlights concepts of using GraphQL with Appollo client.

License

Notifications You must be signed in to change notification settings

Paul-Borisov/nextjs-graphql-countries-with-details-in-dynamic-right-hand-panel

Repository files navigation

Overview

This is an educational Next.js 15 RC + React 19 project for my colleagues, which highlights concepts of using GraphQL with Appollo client.

  • Technical stack: Next.js 15, React 19, TypeScript, GraphQL with Apollo Client and public server endpoint, Tailwind, Radix UI, TanStask Virtual.

  • Homepage queries a public GraphQL service, which returns a list of countries with desired attributes.

Homepage loading in dark system theme

  • Data is presented in a tabular view with multiple attributes including country codes shaped as links.

  • I also added a navigation item to virtual grid with effects of dynamic infinite scroll.

Homepage loaded in dark system theme

  • Click on a country code opens a country page using the standard feature of Next.js dynamic routes like app/[countrycode]/page.tsx

  • The country page queries the same GraphQL service but this time using the filter by "code" like

      query {
        countries(filter: {code: {eq: "countrycode"}}) {
          ...
        }
      }
    
  • If data does not have country name in returned attributes, the logic additionally queries a public REST service supplying the country code to get the name.

Country page loaded in light system theme

Details open in a right-hand side panel in light system theme

Details open in a right-hand side panel in dark system theme

Simple steps to add support of GraphQL to Next.js environments

Use Appollo Client. More details: https://www.apollographql.com/docs/react/get-started

  1. Add two packages npm install @apollo/client graphql

  2. Add the following code to your component

    import {
      ApolloClient,
      InMemoryCache,
      ApolloProvider,
      gql,
    } from "@apollo/client";
    
    const client = new ApolloClient({
      uri: "https://countries.trevorblades.com/", // Put here URL of your GraphQL endpoint (server)
      cache: new InMemoryCache(),
    });
    
    const queryFilter = '(filter: {currency: {eq: "EUR"}})';
    client
      .query({
        query: gql`
        query {
          countries${queryFilter} {
            name: awsRegion
            capital
            code
            continent {
              code
              name
            }
            currencies
            currency
            languages {
              code
              name
              native
            }
            phone
            phones
            states {
              code
              country {
                name
              }
              name
            }
          }
        }
     `,
      })
      .then((result) => console.log(result));
  3. You can also test simple GraphQL queries locally in the browser's console. For instance:

    • Open the site https://flyby-router-demo.herokuapp.com/ to be compliant with their Content Security Policy directives.
    • While staying on the same page, open Dev Tools (by pressing F12 in Chrome) and enter the following code into the console.
    fetch("https://flyby-router-demo.herokuapp.com/", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({
        query: `query GetLocations {
        locations {
          id
          name
          description
          photo
        }
      }`,
      }),
    })
      .then((r) => r.json())
      .then((data) => console.log(data));

User interface

  • The UI adjusts automatically to using a current system theme of user's environment, dark or light.

  • A combination of loading.tsx + Suspense + fallback Shimmer control highlights usage of lazy server-side data loading.

    • Also, the server component components/server/ContentHomeCountry.tsx loads dynamically a client side component with disabled SSR.

    • This technique demonstrates how to solve classic SSR problems with using window and other client side only objects ported from old codebases.

  • Country page demonstrates usage of Radix UI Themes controls from the package @radix-ui/themes.

    • Details button visible on the page opens a right-hand side panel, which is made of slightly tweaked Radix UI Dialog.

    • All page elements support dynamic detection of a system theme change and correctly reflect this change with no page reloading.

      • For instance, open the right-hand side panel and change system theme from light to dark. The panel should correctly reflect this change.

      • The logic uses window.matchMedia("(prefers-color-scheme: dark)") with change event listener. Please refer to shared/hooks/useSystemDarkMode.ts.

    • The codebase includes a few useful tailor-made features managed by settings in .env file.

      • pagecachetimeout=15: demostrates how to persist cache data on all pages for 15 seconds in production builds.

        • To show this, the first row in the home page table gets a test value with dynamic Phone property. This data persists for 15 seconds and then gets updated.
      • showVerticalScrollbar=true: demostrates correct settings of Radix Dialog to suppress undesired UI-layout shifts on opening the right-hand side panel in the browser window with a visible vertical scrollbar.

      • disableSidePanelLightClosing=true: demostrates how to prevent accidental closing of the right-hand side panel on "mouse click outside" and "ESC key press" events.

  • CSS styling uses a combination of global.css, Tailwind, and modules to highlight different ways of using styles.

Getting Started

Clone this project.

Review / adjust default settings found in .env

endpointCountryByCode=https://restcountries.com/v3.1/alpha/{countryCode}
endpointGraphqlCountries=https://countries.trevorblades.com/
apiKeyGql="for instance, an api key for your GQL endpoint"
pagetitlehome="Next.js 15 with GraphQL/Apollo"
pagedescriptionhome="Example of Next.js 15 app with GraphQL queries via Appollo Client"
pageheader="Next.js 15 app with GraphQL queries via Appollo Client"
pagecachetimeout=15 # seconds, for production builds
showVerticalScrollbar=true
disableSidePanelLightClosing=true

Install modules

npm i

Start the dev server

npm run dev

Open http://localhost:3000 and load the home page.

About

This is an educational project in Next.js 15 RC + React 19 for my colleagues, which highlights concepts of using GraphQL with Appollo client.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published