skip to Main Content

I want to render the page on build and therefore I need to validate params properly in Next.JS app router with searchParams.

This is what I want to do: I have the /gallery page, here I show from every photo a main image – the coverImage. Then when I click on a photo I want to display on the /gallery/[id] page more photos of the same kind. Thats what I try to show with my working example on codesandbox.

As you can see my /gallery page:

import Link from "next/link";
import images from "../config/Gallery";
import { Fragment } from "react";
import Image from "next/image";

export default function Gallery({
  searchParams,
}: {
  searchParams: { [key: string]: string | string[] | undefined };
}) {
  const selectedImage = searchParams.id as unknown | number;

  return (
    <div className="flex flex-wrap justify-center">
      <Link href={"/"}>Homepage </Link>
      {images.map((image) => {
        selectedImage === image.id;
        return (
          <Fragment key={image.id}>
            <div className="px-5 py-5">
              <Link href={`/gallery/${image.id}`}>
                <Image
                  src={image.coverImage}
                  title={image.title}
                  alt={image.title}
                  placeholder="blur"
                  height={200}
                />
                <h1>Click on Image! </h1>
              </Link>
            </div>
          </Fragment>
        );
      })}
    </div>
  );
}

I match the selected Image with my searchParams.id. The id in my interface is of type number. But when I change the searchParams to number and remove the unknown | number type from my selectedImage I get the error:

Property 'id' does not exist on type 'number'

My workaround is to use this types for searchParams.

searchParams: { [key: string]: string | string[] | undefined };

And then add as unknown | number to const selectedImage and it works but this is very hacky and not the correct way I guess.

2

Answers


  1. Query params are always of string type (if available).

    As such the below type for searchParams does make sense:

    searchParams: { [key: string]: string | string[] | undefined };
    

    This however do not make sense:

    const selectedImage = searchParams.id as unknown | number;
    

    Since you want selectedImage as Number type, its better to do it runtime (rather than forcing the type on TypeScript).

    const selectedImage = Number(searchParams.id)
    
    • Number("123"); // returns the number 123
    • Number("unicorn"); // NaN
    • Number(undefined); // NaN

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

    In case searchParams.id is not available, you can use a dummy value (so you wont get NaN),

    const selectedImage = Number(searchParams.id ?? -1)
    
    Login or Signup to reply.
  2. if you want get url params element you should try this solution

    import:

    import { useRouter } from 'next/router';
    

    usage:

    const {query: { symbol }} = useRouter();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search