Search code examples
next.js

Next.js router.query returns undefined


I am passing artistName dynamically and want to receive this name in another component that is in app/artist/[artistId]/page.js but can't destructure artistName although it is passing properly.

CollectionItem.js

import Image from "next/image";
import { useRouter } from "next/navigation";

const CollectionItem = ({
    additionalImages,
    collectionName,
    artistImage,
    artistName,
}) => {
    const router = useRouter();

    const handleNavigation = artistName => {
        router.push(`/artist/${artistName}`);
    };

    return (
        <div>
            {additionalImages.slice(0, 1).map((additionalImage, index) => (
                <Image
                    key={index}
                    src={additionalImage}
                    alt="additionalImage"
                    className="w-full md:w-[330px]"
                />
            ))}
            <div className="flex items-center justify-between gap-[15px] mt-[15px]">
                {additionalImages.slice(1, 3).map((additionalImage, index) => (
                    <Image
                        key={index}
                        src={additionalImage}
                        alt="additionalImage"
                        className="w-[95px] md:w-[100px]"
                    />
                ))}
                <div
                    onClick={() => handleNavigation(artistName)}
                    className="flex items-center justify-center bg-[#202020] px-[15px] py-[32px]  w-[95px] md:w-[100px] h-[95px] md:h-[100px] rounded-sm cursor-pointer"
                >
                    <h1 className="text-[22px] font-bold text-[#fff]">
                        {additionalImages.length - 2}+
                    </h1>
                </div>
            </div>
            <div className="text-[#fff] mt-[15px]">
                <h1 className="font-semibold text-[22px]">{collectionName}</h1>
                <div className="flex items-center gap-[12px] mt-[10px]">
                    <Image src={artistImage} alt="artistImage" />
                    <h1>{artistName}</h1>
                </div>
            </div>
        </div>
    );
};

export default CollectionItem;

here is page.js

"use client";
import { useRouter } from "next/navigation";

const ArtistPage = () => {
    const router = useRouter();
    const { artistName } = router.query;
    console.log(artistName);
    return <div className="text-[#ffffff]">Hello {}</div>;
};

export default ArtistPage;

I want to show artistName here in this page.js


Solution

  • As per Next.js 14

    The query object has been removed and is replaced by useSearchParams()

    To get query params, you have to use useSearchParams() like below:

    "use client";
    import { useSearchParams } from "next/navigation";
    
    const ArtistPage = () => {
        const searchParams = useSearchParams();
        const artistName = searchParams.get('artistName');
        console.log(artistName);
        return <div className="text-[#ffffff]">Hello {}</div>;
    };
    
    export default ArtistPage;
    

    Note that even with useSearchParams() this ain't going to work because you are not adding artistName in the query params of the url, edit CollectionItem to something like:

    const handleNavigation = artistName => {
        router.push(`/artist/artists?artistName=${artistName}`);
    };
    

    this will make sure that you are adding the artistName in the query params.

    For more about useSearchParams(), see Next.js docs.