Setting up TanStack Query in Next.js 14 (/app) router

There are so many ways you could have gotten React Query set for your project, the first way would be to visit the official docs, and another way would be to visit StackOverflow. I mean you would love to copy paste the code without knowing what is happening.

But I believe the best and only way would be to read the docs, and yeah I know that the docs can be overwhelming for the little things you want to do, I mean the title of this blog is “Easy Setup”. You want to get it up and running.

In this blog post, I’ll share my documentation on how to setup React Query for your Next.js project using the (/app) router. Before we proceed I just want to say It’s called TanStack router now…

The first step as you know would be to install the necessary packages to make this work, These packages would be the:

  • TanStack React Query package

  • The TanStack Eslint Plugin: This is just to catch errors on time

Install TanStack Query

$ npm i @tanstack/react-query
# or
$ pnpm add @tanstack/react-query
# or
$ yarn add @tanstack/react-query
# or
$ bun add @tanstack/react-query

Recommendations

$ npm i -D @tanstack/eslint-plugin-query
# or
$ pnpm add -D @tanstack/eslint-plugin-query
# or
$ yarn add -D @tanstack/eslint-plugin-query
# or
$ bun add -D @tanstack/eslint-plugin-query

Now that you’ve installed the necessary packages let’s look at how we could initialize TanStack Query for your Next.js project.

Initializing TanStack Query

  1. Create a file at the app directory called tanstack-client.tsx 

  2. Paste the following code:

"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

export function TanStackClient({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  const client = new QueryClient({
    defaultOptions: {
      queries: {
        refetchOnWindowFocus: false, // disable refetching on window focus
      },
    },
  });

  return <QueryClientProvider client={client}>{children}</QueryClientProvider>;
}

Import and Wrap

  1. In your layout.tsx file, import the tanstack-client a component like so:

// ...
import { TanStackClient } from "./tanstack-client";
  1. Still on the layout.tsx file, scroll down till you see a function component that is named RootLayout 

    It looks something like this:

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode,
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}
  1. Surround the HTML element with the tanstack-client component, the HTML element, and its children should be inside the TanStackClient component

    Your code should look like this:

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode,
}>) {
  return (
    <TanStackClient>
      <html lang="en">
        <body className={inter.className}>{children}</body>
      </html>
    </TanStackClient>
  );
}

The reason I gave these steps, is that you can’t parse a client component into a server component. By default, Next.js doesn’t know whether your component is a client or a server component. If you try to use a client function for a server component Next.js would throw an error that simply means “Oh no I detected this as a client function, do you mean to make this component a client component?”

The QueryClient function provided by TanStack Query, is a client function, so this means we need to make a client component, that’s why I created the TanStackClient component, this acts like our Parent Component which is now a client component, and then its children, meaning whatever is rendered underneath remains unchanged, in this case, it’s our RootLayout component.