Provide a way to set the scroll behaviour when using redirect
in a Server Action
#57566
Replies: 8 comments 6 replies
-
I'm using the redirect method from an action to send a request information form and let the user to see a thank you page; the problem is that the form is to the page bottom and after the redirect the scroll still at the same point and not restore to the top. |
Beta Was this translation helpful? Give feedback.
-
Same problem here. Still looking for a solution. |
Beta Was this translation helpful? Give feedback.
-
Why don't you use an const handleSubmit = () => {
window.scrollTo({ top: 0, behavior: "smooth" });
} You could also scroll to a specific position, e.g., where you show a “Thank You” message. You could also check if the form is submitting and wait until it is successfully submitted before scrolling. If JavaScript is disabled, the page will reload and scroll to the top anyway, I think. |
Beta Was this translation helpful? Give feedback.
-
you can add metadata to the redirect URL to e.g. display toasts, scroll pages, etc. this is why the scroll is e.g. to display toasts, you can do export function ActionSuccess(): null {
const toasts = useToasts();
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
React.useEffect(() => {
if (!searchParams.has('action-success')) {
return;
}
toasts.add(
{
message: searchParams.get('action-success') as string,
type: 'success',
},
{ timeout: 5000 },
);
const search = new URLSearchParams(searchParams);
search.delete('action-success');
router.replace(makeURL(pathname, search), { scroll: false });
// eslint-disable-next-line react-hooks/exhaustive-deps -- toasts causes infinite loop
}, [pathname, searchParams, router]);
return null;
} you could make something similar to scrolling, e.g. by doing export function Scroll(): null {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
React.useEffect(() => {
if (searchParams.get('scroll') !== 'true') {
return;
}
const search = new URLSearchParams(searchParams);
search.delete('scroll');
router.replace(makeURL(pathname, search), { scroll: true });
}, [pathname, searchParams, router]);
return null;
} Mount this in your root layout (make sure the file you're exporting this from is This is how success/warn/error banners used to be handled back in PHP days, without the URL cleanup. |
Beta Was this translation helpful? Give feedback.
-
It is ideal for the framework to manage scrolling. Scrolling is already managed on client side redirects. It would be great to expect similar scroll behavior when doing server side redirects. |
Beta Was this translation helpful? Give feedback.
-
So the workaround is to use |
Beta Was this translation helpful? Give feedback.
-
Another workaround is just to have a component that scrolls to top: "use client";
import { useEffect } from "react";
export default function ScrollToTop() {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return null;
} Then in any |
Beta Was this translation helpful? Give feedback.
-
Is there any update to this? |
Beta Was this translation helpful? Give feedback.
-
Goals
redirect
in Server Actions, similar torouter.push
androuter.replace
on the client.Non-Goals
Everything else regarding Server Actions works fine for me :)
Background
When using
router.push
,router.replace
andLink
we can define whether to scroll to the top of the page or remain the position via ascroll
option. When usingredirect
in a Server Action the app currently behaves as if{ scroll: false }
was passed torouter.push
.However, there are use cases where a Server Action
redirect
should scroll to the top and other use cases where the scroll position should be kept unchanged by aredirect
.Proposal
Instead of providing a
redirect
function like thisredirect(path, type)
, the second argument could be made an object of options. In Server Actions, or generally in a Streaming Context ascroll
option could be made available when usingredirect
.E.g.:
`
Beta Was this translation helpful? Give feedback.
All reactions