iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🍣

How to Get URL Query Parameters in Next.js 13 App Router

に公開

Overview

I ran into some trouble while trying to get query parameters in Next.js 13's App Router, so I'm writing this memo.
Previously, using useRouter was the standard way to get them, but using it as-is results in the following error:

ReactServerComponentsError:

You have a Server Component that imports next/router. Use next/navigation instead.
Learn more: https://nextjs.org/docs/app/api-reference/functions/use-router

Environment

  • Next.js 13.4
  • App Router

Code

When Getting in Client Components

This method is straightforward.
You should be able to find it quickly with a search.

page.tsx
"use client";

import { useSearchParams } from "next/navigation";

export default function Page() {
  const searchParams = useSearchParams();
  const pageNum = searchParams.get("page");

  return (
      <>
          <h1>Page</h1>
          <p>page: {pageNum}</p>
      </>
  );
}

Reference: Functions: useSearchParams | Next.js

When Getting in Server Components

Note on useSearchParams

As stated in the Next.js documentation regarding the use of "use client" to make a component a Client Component, "Once 'use client' is defined in a file, all other modules imported into it, including child components, are considered part of the client bundle." There are likely cases where you want to keep components as Server Components as much as possible.

Once "use client" is defined in a file, all other modules imported into it, including child components, are considered part of the client bundle.

Reference: Getting Started: React Essentials | Next.js

However, useSearchParams is only available in Client Components. Therefore, if you don't specify "use client" and leave it as a Server Component, an error will occur as shown below.

page.tsx
import { useSearchParams } from "next/navigation";

export default function Page() {
  const searchParams = useSearchParams();
  const pageNum = searchParams.get("page");

  return (
      <>
          <h1>Page</h1>
          <p>page: {pageNum}</p>
      <//>
  );
}

Error: useSearchParams only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component

This is where I got stuck.

Solution

The solution is quite simple.
You can retrieve query parameters in a Server Component by specifying searchParams in the props and getting the values from there.

page.tsx
export default function Page({
  params,
  searchParams,
}: {
  params: { slug: string };
  searchParams: { [key: string]: string | string[] | undefined };
}) {
  const pageNum = searchParams.page;

  return (
    <>
      <h1>Page</h1>
      <p>page: {pageNum}</p>
    </>
  );
}

Reference: File Conventions: page.js | Next.js

As expected, it is important to read the documentation thoroughly when working with new technologies.

Thank you for reading.

Discussion