@Rafal Potasz Not sure what solution you came up with, but I tried my hand and made something work:
https://github.com/StevenStavrakis/svelte5-gsap-scrollsmoother
(You'll have to install GSAP yourself because I get a 403 when trying to use the private npm registry for some reason)
The meat of the code is here:
<script lang="ts">
import "../app.css";
import { navigating } from "$app/stores";
import { ScrollSmoother } from "gsap/ScrollSmoother";
import {ScrollTrigger} from "gsap/ScrollTrigger";
import gsap from "gsap";
let { children } = $props();
gsap.registerPlugin(ScrollSmoother, ScrollTrigger);
$effect(() => {
// on first load, we need to create the smoother
ScrollSmoother.create({
wrapper: "#smooth-wrapper",
content: "#smooth-content",
});
})
$effect(() => {
const smoother = ScrollSmoother.get();
if ($navigating === null) {
// When navigating is null, that means we are no longer navigating; the page has been loaded
ScrollSmoother.refresh();
} else {
// when we start navigating, we scroll to the top otherwise we get some weird behavior
if (!!smoother) {
smoother.scrollTo(0)
}
}
});
</script>
<div class="flex" id="smooth-wrapper">
<div class="h-screen w-[200px] bg-slate-600 text-white p-8">
<h2 class="text-xl font-bold">Menu</h2>
<a class="block" href="/">Home</a>
<a class="block" href="/second-page">Second page</a>
</div>
<div class="w-full" >
<div id="smooth-content">
{@render children()}
</div>
</div>
</div>
It makes use of effects and the `navigating` store. There is some strange behavior where the scroll position isn't reset when navigating pages, so I just force a scroll to the top of page. I'm sure there is a more elegant way to deal with it, but that is probably already covered in another post.