# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://132oq-szjxckld--diwejk1k2j-1123n.gitbook.io/documentation-studio-shento/installing-useful-libraries/installing-locomotive-scroll-with-svelte-5-and-sveltekit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
