Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEXT-1147] Scroll position is reset when search params are updated #49087

Closed
1 task done
benjaminwaterlot opened this issue May 2, 2023 · 73 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@benjaminwaterlot
Copy link

benjaminwaterlot commented May 2, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Next.js `13.3.5-canary.2`

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/modest-gould-h4nlvd?file=%2Fapp%2Fpage.tsx&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A7%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A7%7D%5D

To Reproduce

  • Click the counter to update client state.
  • Scroll a little.
  • Click the second button to update search params.
  • The client state is preserved, but the scroll position is lost.

Describe the Bug

Context

In Next <= 13.2.4, updating search params was working as intended : client state was kept, and scroll position was kept too.

In Next 13.2.5, a regression made the client components unmount and remount when search params were updated.

@feedthejim fixed that unmounting in #49047 (it's testable on 13.3.5-canary.2), but there is still an issue now: scroll position is lost on search params updates.

Problem: persisting state in search params is very important with the App router - that's a clean way for client components to request updated data from the RSC.

Reproduction Codesandbox

Here's a codesandbox reproducing the bug:

https://codesandbox.io/p/sandbox/modest-gould-h4nlvd?file=%2Fapp%2Fpage.tsx&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A7%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A7%7D%5D

In video

CleanShot.2023-05-02.at.14.18.36-converted.mp4

A real-world example of the problem

Previously, the "name for the fund", kept in client state, was reset when updating the sliders. It's now better, but the scroll position reset is still awkward.

CleanShot.2023-05-02.at.14.31.38.mp4

Expected Behavior

When updating search params, the scroll position should be preserved.

Which browser are you using? (if relevant)

Latest stable Google Chrome

How are you deploying your application? (if relevant)

No response

NEXT-1147

@benjaminwaterlot benjaminwaterlot added the bug Issue was opened via the bug report template. label May 2, 2023
@schimi-dev
Copy link

Looking forward to this getting fixed :-)

@aaron5670
Copy link

aaron5670 commented May 2, 2023

I experience the same issue... I thought it was a bug in my code. 😆

@timneutkens timneutkens added the linear: next Confirmed issue that is tracked by the Next.js team. label May 10, 2023
@timneutkens timneutkens changed the title Scroll position is reset when search params are updated [NEXT-1147] Scroll position is reset when search params are updated May 10, 2023
BarnabyBishop added a commit to Thinkmill/keystatic that referenced this issue May 18, 2023
@adrianhajdin
Copy link

adrianhajdin commented May 27, 2023

I'm experiencing the same bug. The website scrolls to the top every time the URL parameters change.

I saw @timneutkens's tweet on the topic.

2023-05-27.09-58-58.mp4

@Tony0205
Copy link

I'm having the same problem...
And it seems that the page still remounts when the search param is changed.

My nextJS version is 13.4.5-canary.0

It seems to be fine when I use English, but when I use Korean, it keeps reloading.

@Deepakv1111
Copy link

@adrianhajdin I'm having the same issue...

@YoussefKababe
Copy link

YoussefKababe commented Jun 9, 2023

Facing the same issue... First I would like to mention that I think this is a correct behavior by default, there nothing wrong with it; however, it would be awesome to have the option to persist scroll position indeed.

I came up with a quick workaround to solve this temporarily until there's an official fix:

'use client'
import { useCallback, useEffect } from 'react'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'

export default function ExampleClientComponent(): JSX.Element {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()

  useEffect(() => {
    // Retrieve scrollY value from localStorage after routing
    const persistentScroll = localStorage.getItem('persistentScroll')
    if (persistentScroll === null) return

    // Restore the window's scroll position
    window.scrollTo({ top: Number(persistentScroll) })
   
    // Remove scrollY from localStorage after restoring the scroll position
    // This hook will run before and after routing happens so this check is
    // here to make we don't delete scrollY before routing
    if (Number(persistentScroll) === window.scrollY)
      localStorage.removeItem('persistentScroll')
  }, [searchParams])

  const setSearchParam = useCallback(
    (key: string, value: string) => {
      const currentParams = searchParams.toString()
      const params = new URLSearchParams(currentParams)

      params.set(key, value)
      // If search params are still the same there's no need to do anything
      if (currentParams === params.toString()) return

      // Save current scrollY value to localStorage before pushing the new route
      localStorage.setItem('persistentScroll', window.scrollY.toString())
      router.push(`${pathname}?${params.toString()}`)
    },
    [searchParams, pathname, router],
  )

  return (
    <button
      onClick={() => {
        setSearchParam('exampleParam', '9999')
      }}
    >
      Update search params
    </button>
  )
}

Depending on your application's logic, you can package this into a React hook and reuse it in all components that should update the search params.

@GBrachetta
Copy link

@adrianhajdin I got it working by using "next": "13.2.4" in package.json (and obviously running npm i afterwards) and adding

  experimental: {
    appDir: true,
  },

in next.config.js.

At least this works fine while keeping server side rendering until they fix the bug.
This might be better than converting the component to client side rendering.

@AdiAkhileshSingh15
Copy link

AdiAkhileshSingh15 commented Jun 13, 2023

@GBrachetta it won't work when deployed i guess.

So, i would suggest people to use that method of restoring the scroll position as shown by @YoussefKababe , that will work in the deployed version as well, though it seems to make a page reload or smthng, but as @GBrachetta said, atleast it's better than converting the component to client side rendering, till the bug's fixed.

@jeeknowme
Copy link

jeeknowme commented Jun 18, 2023

I'm experiencing the same bug. The website scrolls to the top every time the URL parameters change.

I saw @timneutkens's tweet on the topic.

2023-05-27.09-58-58.mp4

What i have done in the project I followed from you is that I've just put id="searchbar" in the form then append #searchbar in
router.push(${newPathname}#searchbar)
so that every changes in url, it directly goes in the dropdown, just having a slight navigation after.
Although this still doesn't resolve the issue, I can still use server side rendering from this.

@lucasoz
Copy link

lucasoz commented Jun 20, 2023

Same issue in "next": "13.4.6"

@kbateman-we
Copy link

I'm seeing lots of router fixes in 13.4.6 and 13.4.7-canary* ref. https://github.com/vercel/next.js/releases, but no notes addressing this issue.

Anyone know if a fix for this is in the works anytime soon?

@abhishekmardiya
Copy link

I'm encountering a similar issue where the webpage consistently jumps to the top whenever there is a modification to the URL parameters.

@malburo
Copy link

malburo commented Jun 23, 2023

same issue :(

@amanchev
Copy link

Same issue.

@ginabeki
Copy link

Same issue :(

@weronikadominiak
Copy link

Same issue.

1 similar comment
@dihan48
Copy link

dihan48 commented Jun 25, 2023

Same issue.

@e2goon
Copy link

e2goon commented Jun 25, 2023

https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#scrolling-to-an-id

image

<Link href="/#hashid" scroll={false}>
  Scroll to specific id.
</Link>

This code does not work with scroll={false}.
Can the scroll={false} option universally prevent scrolling to the top, not just with hash routing?

@kusalkalinga00
Copy link

same issue

@steadyGuy
Copy link

This issue is really frustrating. I don't want to downgrade my next.js to 13.2.4 just to resolve this bug, or else I will get other unresolved problems.

@aaron5670
Copy link

Same issue, really annoying and a bit blocking.. 🙄

@timneutkens
Copy link
Member

doesn't work as expected. It's still causing a scroll to top. Adding an empty string fixes it though.

Please provide a reproduction.

@lmatteis
Copy link

lmatteis commented Jul 28, 2023

@timneutkens

Please provide a reproduction.

#49087 (comment)

@timneutkens
Copy link
Member

@lmatteis I'm guessing you're referring to the reproduction for the scroll being reset when searchParams change. That one I can easily reproduce as of right now it's expected behavior as I shared in #49087 (comment). The comment linked to does not have scroll={false} / scroll: false anywhere. @adrivelasco is claiming router.push with scroll: false doesn't work, that's what I'd like to see a reproduction of.

@adrivelasco
Copy link

@lmatteis I'm guessing you're referring to the reproduction for the scroll being reset when searchParams change. That one I can easily reproduce as of right now it's expected behavior as I shared in #49087 (comment). The comment linked to does not have scroll={false} / scroll: false anywhere. @adrivelasco is claiming router.push with scroll: false doesn't work, that's what I'd like to see a reproduction of.

oh I thought router.push('/', { scroll: false }); was what fixes the issue of: scroll being reset when searchParams change. per what you said, scroll being reset is an expected behavior?

+info: I'm using use-query-params with a Next.js adapter. I was able to fix this bug only by this workaround.

@rupin27
Copy link

rupin27 commented Jul 30, 2023

@adrianhajdin
Adding {scroll: false} fixed it for me. Here is my package.json file:

In router.push(newPathName, {scroll: false});

package.json:

{
  "name": "XYZ",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^1.7.16",
    "@types/node": "20.4.5",
    "@types/react": "18.2.17",
    "@types/react-dom": "18.2.7",
    "autoprefixer": "10.4.14",
    "next": "13.4.12",
    "postcss": "8.4.27",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.1.6"
  }
}

@ShivangKakkar
Copy link

@adrianhajdin Adding {scroll: false} fixed it for me. Here is my package.json file:

In router.push(newPathName, {scroll: false});

package.json:

{
  "name": "XYZ",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^1.7.16",
    "@types/node": "20.4.5",
    "@types/react": "18.2.17",
    "@types/react-dom": "18.2.7",
    "autoprefixer": "10.4.14",
    "next": "13.4.12",
    "postcss": "8.4.27",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.1.6"
  }
}

Thanks, that works!

@momenqudaih
Copy link

Adding {scroll: false} fixed it for me, with Next 13.4.12 release.❤️

In router.push(newPathName, {scroll: false} );

@denisonkolling
Copy link

denisonkolling commented Aug 9, 2023

@momenqudaih @ShivangKakkar @rupin27

Thanks guys, also worked here... "next": "13.4.12" with router.push(newPathName, {scroll: false} );

@leerob
Copy link
Member

leerob commented Aug 9, 2023

Got some docs going here, thanks folks 🙏

#53804

Edit: wrong button, disregard

@leerob leerob closed this as completed Aug 9, 2023
@leerob leerob reopened this Aug 9, 2023
kodiakhq bot pushed a commit that referenced this issue Aug 10, 2023
Addressing comments from #49087.
Introduced with #51869.
Related #50105.

This PR adds documentation for `next/link` and useRouter` about how to disable scroll restoration.
@hikiasi

This comment was marked as off-topic.

yeolyi added a commit to wafflestudio/csereal-web that referenced this issue Aug 25, 2023
next.js 버전 업데이트하니까 됨,, 뭐냐? vercel/next.js#49087 (comment). 심지어 useParams 리턴값도 바뀜..₩
@SergiiSechka

This comment was marked as off-topic.

@SergiiSechka

This comment was marked as off-topic.

@vercel vercel locked and limited conversation to collaborators Aug 28, 2023
@vercel vercel unlocked this conversation Aug 28, 2023
yeolyi added a commit to wafflestudio/csereal-web that referenced this issue Aug 29, 2023
* body에 overscroll-none 적용

* SelectionList에서 스크롤되는 문제 수정

next.js 버전 업데이트하니까 됨,, 뭐냐? vercel/next.js#49087 (comment). 심지어 useParams 리턴값도 바뀜..₩

* 찾아오는 길 내용 추가

* 학부 수시 모집 데이터 추가

* 링크 수정

* 동아리 소개 문단 조정

* 동아리 소개 디자인 QA 반영

* 입학 관련 데이터 추가

* 디자인 QA 반영

* 디자인 QA 반영

* faculty와 staff 폴더 통합

* facultyList 데이터 추가

* EmiritusFaculty 추가

* EmiritusFaculty 타입 추가

* 교수진 상세 정보 추가

* EmiritusFaculty 관련 타입 정리

* SimpleEmeritusFaculty 데이터 추가

* 역대교수 관련 row 처리

* EmeritusFaculty page 레이아웃 수정

* 역대교수 상세정보 추가

* 행정직원 관련 타입 정리

* staffList 데이터 추가

* staff 정보 추가

* overscroll-none 제거

* TCL 정보 추가

* ResearchLabInfo 관련 타입 정리

* researchLabInfos 추가

* StaffMemberPage에 mock api 적용, server component로 변경

* researchLabInfos에 professors 추가

* faculties labId 추가

* description 제외 researchLabs 정보 추가

* 연구실 상세 데이터 구조 개발

* description txt파일들 추가

* 연구실 상세 정보 진행중

* 연구실 상세 정보 추가

* usePost 삭제

* 리뷰 반영

* 모달 로직 수정

* 다크 모드 적용
@HaKiLo91

This comment was marked as spam.

@Zukhriddinbek-Code
Copy link

I also have same issue, unfortunately in a project we have to switch from server to client side

@Achour
Copy link

Achour commented Sep 10, 2023

I'm experiencing the same bug. The website scrolls to the top every time the URL parameters change.

I saw @timneutkens's tweet on the topic.

2023-05-27.09-58-58.mp4
try this:
router.push(newPathName, { scroll: false })
it will fix the issue

@alexhollender
Copy link

alexhollender commented Sep 12, 2023

version: "next": "13.4.19"
router: app router
solution: adding { scroll: false } to my router.push() call fixed the issue, for example:

router.push(`${pathname}${updatedSearchParams}`, {scroll: false});

documentation: https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#disabling-scroll-restoration

thanks @timneutkens for the solution

@Mishael-Joe
Copy link

@ShivangKakkar thanks too
@adrianhajdin Adding {scroll: false} fixed it for me. Here is a screenshot of the solution:

In router.push(newPathName, {scroll: false});

searchparams

@crisner1978
Copy link

you can set the scroll options and this will prevent the scrolling when trying to change your searchParams

router.push(newPathname, { scroll: false})

@timneutkens
Copy link
Member

I'm going to lock this issue as it's already part of our issue tracker and the same solution keeps being repeated which causes notifications to everyone in this thread.

@vercel vercel locked as spam and limited conversation to collaborators Sep 14, 2023
@samcx
Copy link
Member

samcx commented Jan 2, 2024

Hi everyone!

I will be moving this to :nextjs: Discussions as this is no longer an active issue (locked), and the solution is shared above.

Happy 2024!

@samcx samcx converted this issue into discussion #60146 Jan 2, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests