> For the complete documentation index, see [llms.txt](https://132oq-szjxckld--diwejk1k2j-1123n.gitbook.io/documentation-studio-shento/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://132oq-szjxckld--diwejk1k2j-1123n.gitbook.io/documentation-studio-shento/installing-useful-libraries/installing-locomotive-scroll-with-svelte-5-and-sveltekit.md).

# Installing Locomotive Scroll with Svelte 5 and SvelteKit

## Installation

First, let's install the necessary packages:

{% tabs %}
{% tab title="Terminal" %}

```bash
npm install locomotive-scroll@beta
```

{% endtab %}
{% endtabs %}

## Create a Locomotive Scroll Store

We'll start by creating a Svelte store to manage our Locomotive Scroll instance:

{% tabs %}
{% tab title="src/lib/locomotiveScroll.js" %}

```javascript
import { writable } from "svelte/store";

export const locomotiveScroll = writable(null);

export async function initLocomotiveScroll(options = {}) {
  if (typeof window !== "undefined") {
    const LocomotiveScroll = (await import("locomotive-scroll")).default;
    const instance = new LocomotiveScroll({
      el: document.querySelector("[data-scroll-container]"),
      lenisOptions: {
        ...options,
      },
    });
    locomotiveScroll.set(instance);
    return instance;
  }
}
```

{% endtab %}
{% endtabs %}

This code creates a Svelte store called `locomotiveScroll` and an initialization function `initLocomotiveScroll`. The function dynamically imports Locomotive Scroll, creates an instance, and stores it in the `locomotiveScroll` store.

{% hint style="info" %}
The `initLocomotiveScroll` function is designed to work in a browser environment, which is why it checks if `window` is defined before proceeding.
{% endhint %}

## Set Up the Layout Component

Next, we'll set up our layout component to initialize Locomotive Scroll:

{% tabs %}
{% tab title="src/routes/+layout.svelte" %}

```html
<script>
	import { browser } from '$app/environment';
	import { afterNavigate } from '$app/navigation';
	import { page } from '$app/stores';
	import { initLocomotiveScroll, locomotiveScroll } from './locomotiveScroll.js';
	import './locomotive-scroll.css';

	let scrollInstance = $state(null);

	const { children, settings } = $props();

	async function initializeScroll() {
			if (scrollInstance) {
					scrollInstance.destroy();
			}
			console.log('Initializing new scroll instance');
			scrollInstance = await initLocomotiveScroll(settings);
	}

	afterNavigate(async () => {
			if (browser) {
					await initializeScroll();
					scrollInstance.scrollTo(0, { duration: 100, disableLerp: true });
			}
	});
</script>

<div data-scroll-container>
	{@render children()}
</div>
```

{% endtab %}

{% tab title="src/lib/locomotive-scroll.css" %}

```css
html.lenis{height:auto}.lenis.lenis-smooth{scroll-behavior:auto}.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}.lenis.lenis-stopped{overflow:hidden}.lenis.lenis-scrolling iframe{pointer-events:none}
```

{% endtab %}
{% endtabs %}

This layout component initializes Locomotive Scroll when the component mounts and updates it when the route changes. It also ensures that Locomotive Scroll is destroyed when the component unmounts.

{% hint style="info" %}
The `$state`, `$props()`, and `$effect` syntax are specific to Svelte 5's new reactive primitives. They replace the older `let`, `export let`, and `$:` syntax respectively.
{% endhint %}

## Using Locomotive Scroll in a Page Component

Finally, let's see how to use Locomotive Scroll in a page component:

{% tabs %}
{% tab title="src/routes/+page.svelte" %}

```html
<script>
	import { browser } from '$app/environment';
	import { locomotiveScroll } from '$lib/locomotiveScroll';

	$effect(() => {
		if (browser && $locomotiveScroll) {
			console.log('Locomotive Scroll is ready');
			// You can now use $locomotiveScroll methods
		}
	});
</script>

<div data-scroll-section class="h-[1000px] flex flex-col justify-center items-center">
	<h2 data-scroll data-scroll-speed="0.8">What's up?</h2>
	<p data-scroll data-scroll-speed="0.5">😬</p>
</div>
```

{% endtab %}
{% endtabs %}

This page component demonstrates how to access the Locomotive Scroll instance and use its data attributes for scroll animations.

{% hint style="warning" %}
Make sure to wrap your content in elements with the `data-scroll-section` attribute, and use `data-scroll` and `data-scroll-speed` attributes on elements you want to animate.
{% endhint %}

#### Result

When implemented correctly, you should see a smooth scrolling effect with animated elements. Here's a visual representation of what you might see:

{% tabs %}
{% tab title="localhost:3000" %}
\[A webpage with a centered column of text]

What's up?

😬

\[The text "What's up?" moves slightly as you scroll, while the emoji moves more dramatically due to its higher scroll speed]
{% endtab %}
{% endtabs %}

### Explanation of Key Concepts

1. **Svelte Stores**: The `locomotiveScroll` store is used to make the Locomotive Scroll instance accessible throughout the app.
2. **Dynamic Imports**: Locomotive Scroll is imported dynamically to ensure it only loads in the browser environment.
3. **Lifecycle Management**: The layout component initializes Locomotive Scroll on mount and destroys it on unmount.
4. **Route Change Handling**: The scroll instance is updated when the route changes to ensure smooth transitions between pages.
5. **Data Attributes**: Locomotive Scroll uses data attributes like `data-scroll-container`, `data-scroll-section`, and `data-scroll` to manage scrolling behavior and animations.
