Next.js Discord

Discord Forum

Page redirecting back to previous search page on refresh, See Video attached

Answered
Basset Artésien Normand posted this in #help-forum
Open in Discord
Basset Artésien NormandOP
Please see attached video. Page redirecting back to search page on refresh.
Answered by averydelusionalperson
export const Search = () => {
  const searchParams = useSearchParams()
  const router = useRouter();
  const pathName = usePathName();


  const search = searchParams.get('query')

  const [text, setText] = useState(search ?? '');

  useEffect(() => {
    search && setText(search)
  }, [search])

  return (
    <search className="flex flex-row items-center justify-center px-2 py-3 text-gray-600 ">
      <input
        className="border-big-stone-500 h-10 rounded-full border-2 bg-white px-5 pr-16 text-sm focus:outline-none md:h-8"
        type="search"
        name="search"
        placeholder="Search"
        defaultvalue={text}
      />
      <MagnifyingGlassIcon className="relative right-10 size-5 text-gray-600" onClick={() => {
        const page = pathName.split('/')[1];

        router.push(`/${page}?query=${text}`)
      }} />
    </search>
  )
}


I've added what I think should work in the onClick of the icon, check and modify it to your needs.
View full answer

80 Replies

Basset Artésien NormandOP
Code for "More" Button
      <Button asChild size="lg" variant="primary">
        <Link
          href={{
            pathname,
            query: {
              ...(query ? { query } : {}),
            },
          }}
        >
          More
        </Link>
      </Button>
what is stored in the pathname variable?
Basset Artésien NormandOP
export default async function Page({ searchParams: { query = '' } }: Props) {
  if (!query) return <p>No Search Query</p>

  const sections = [
    {
      header: 'movies',
      pathname: '/movies',
      fetcher: () => api.tmdbRouter.searchMovie.query({ query }),
    },
    {
      header: 'series',
      pathname: '/series',
      fetcher: () => api.tmdbRouter.searchSerie.query({ query }),
    },
  ]

  return (
    <div className="grid grid-cols-1 grid-rows-2 items-center gap-5 px-28 py-6">
      {sections.map((s) => (
        <div
          key={s.header}
          className="flex flex-col items-center justify-center gap-3"
        >
          <MediaHeader header={s.header} pathname={s.pathname} query={query} />
          <Suspense fallback={<CardsSkeleton length={6} />}>
            <MediaDisplay fetcher={s.fetcher} />
          </Suspense>
        </div>
      ))}
    </div>
  )
}

Here is where it comes from. And pathname is both /moviesand /series
so i get redirected to /movies or series. but then when i refresh i get redirected back to search
found it. its this in the navbar search component
 useEffect(() => {
    if (initialRender.current) {
      initialRender.current = false
      return
    }

    if (query) {
      router.push(`/search?query=${query}`)
    }
  }, [query, router])
sed
Basset Artésien NormandOP
?
nothing, so it's solved right?
Basset Artésien NormandOP
yes! thanks for the help anyway
meh, I did nothing
Basset Artésien NormandOP
Would there be a better way of doing this?
    if (query) {
      router.push(`/search?query=${query}`)
    }
so i could use the queryparam on different pages
@averydelusionalperson meh, I did nothing
Basset Artésien NormandOP
well you responded at least
Basset Artésien NormandOP
so i have the queryparam on /search and also on /movies
redirect to /movies with the query param
Basset Artésien NormandOP
but the way its setup now is that search component is always listening for query param and redirecting to /search when it finds it
@@ts-ignore redirect to `/movies` with the query param
Basset Artésien NormandOP
What do you mean?`then it wouldnt redirect to search when typing in the search box
@Basset Artésien Normand but the way its setup now is that search component is always listening for query param and redirecting to /search when it finds it
get the current path by using usePathName(). and redirect to perspective paths with searchParams?
yeah, he wants to change that
@@ts-ignore based on your current logic it will go back to `/search`
Basset Artésien NormandOP
exactly
so i have a search page which shows results for both movies and series and then the user can click "more" to be redirected to /movies or /series.
yes
and you want to search in those pages too?
Basset Artésien NormandOP
yes
without going back to /search ?
Basset Artésien NormandOP
yes
then remove that useEffect?
Basset Artésien NormandOP
and then how would search work then
if its not listening to the query param
why would search listen to query params?
the query params should change based on the search input
Basset Artésien NormandOP
export const Search = () => {
  const searchParams = useSearchParams()

  const search = searchParams.get('query')
  const initialRender = useRef(true)

  const [text, setText] = useState('')

  const query = useDebounce(text, 750)
  const router = useRouter()

  useEffect(() => {
    search && setText(search)
  }, [search])

  useEffect(() => {
    if (initialRender.current) {
      initialRender.current = false
      return
    }

    if (query) {
      router.push(`/search?query=${query}`)
    }
  }, [query, router])

  return (
    <search className="flex flex-row items-center justify-center px-2 py-3 text-gray-600 ">
      <input
        className="border-big-stone-500 h-10 rounded-full border-2 bg-white px-5 pr-16 text-sm focus:outline-none md:h-8"
        type="search"
        name="search"
        placeholder="Search"
        onChange={(e) => setText(e.target.value)}
        value={text || ''}
      />
      <MagnifyingGlassIcon className="relative right-10 size-5 text-gray-600" />
    </search>
  )
}
this is it currently
lemme modify it
export const Search = () => {
  const searchParams = useSearchParams()
  const router = useRouter();
  const pathName = usePathName();


  const search = searchParams.get('query')

  const [text, setText] = useState(search ?? '');

  useEffect(() => {
    search && setText(search)
  }, [search])

  return (
    <search className="flex flex-row items-center justify-center px-2 py-3 text-gray-600 ">
      <input
        className="border-big-stone-500 h-10 rounded-full border-2 bg-white px-5 pr-16 text-sm focus:outline-none md:h-8"
        type="search"
        name="search"
        placeholder="Search"
        defaultvalue={text}
      />
      <MagnifyingGlassIcon className="relative right-10 size-5 text-gray-600" onClick={() => {
        const page = pathName.split('/')[1];

        router.push(`/${page}?query=${text}`)
      }} />
    </search>
  )
}


I've added what I think should work in the onClick of the icon, check and modify it to your needs.
Answer
this is my general idea of how it should be implemented
you can change to your needs
Basset Artésien NormandOP
Looks good.
This also works i just tested from when i did the nextjs-dashboard course
'use client'

import { MagnifyingGlassIcon } from '@heroicons/react/20/solid'
import { useRouter, useSearchParams } from 'next/navigation'
import { useDebouncedCallback } from 'use-debounce'

export const Search = () => {
  const searchParams = useSearchParams()
  const { push } = useRouter()

  const handleSearch = useDebouncedCallback((s: string) => {
    const params = new URLSearchParams(searchParams)
    s ? params.set('query', s) : params.delete('query')
    push(`/search?${params.toString()}`)
  }, 300)

  return (
    <search className="flex flex-row items-center justify-center px-2 py-3 text-gray-600 ">
      <input
        className="border-big-stone-500 h-10 rounded-full border-2 bg-white px-5 pr-16 text-sm focus:outline-none md:h-8"
        type="search"
        name="search"
        placeholder="Search"
        onChange={(e) => handleSearch(e.target.value)}
        defaultValue={searchParams.get('query')?.toString()}
      />
      <MagnifyingGlassIcon className="relative right-10 size-5 text-gray-600" />
    </search>
  )
}
yes it does, but instead of pusing to the /search, you need to push to the current page
I implemented that using pathName
Basset Artésien NormandOP
not sure that will work
as the search is not a page you can navigate too directly. only when typing in search box can you get to that page
wdym by search is not a page?
Basset Artésien NormandOP
i mean, it is a page
but not one that has a nav link you can click on to get there.
You only get there by searching in the navbar search box
but it's still a page?
and the code is for the search input, not search page?
Basset Artésien NormandOP
@averydelusionalperson and the code is for the search input, not search page?
Basset Artésien NormandOP
exactly
maybe there is a better way i can do this
what are you expecting tho?
you want the navbar search for only search page?
Basset Artésien NormandOP
yeah i wasn't sure how i would get it to change between pages
so, you don't want search in /movies page?
Basset Artésien NormandOP
yeah i do
but not from navbar search?
Basset Artésien NormandOP
maybe i can get it to work between different pages
@averydelusionalperson but not from navbar search?
Basset Artésien NormandOP
both
so, navbar search should redirect to '/search'
but still search movies when in movies page?
Basset Artésien NormandOP
^that wouldnt work would it?
no, it wouldn't
but it would if you keep both series, movies in same page
and keep the collection in the queryparams
like /search?query=abcd&collection=movies
that way you still redirect to /search page
and will still search through respective collection
Basset Artésien NormandOP
yeah i am unsure what to do now
here is the code so far if you are interested
you can choose whatever you want, if you have any questions, ask in #help-forum
so, should we consider this thread completed for now?
Basset Artésien NormandOP
sure
thanks
🫡
mark the message that helped you as solution, and the thread will be closed.