# OpenCut Web App Scroll Restoration with TanStack Router

> Implement scroll restoration in your OpenCut web app using TanStack Router. Enable seamless navigation with automatic scroll behavior for a better user experience.

- Repository: [OpenCut.app/OpenCut](https://github.com/OpenCut-app/OpenCut)
- Tags: how-to-guide
- Published: 2026-06-23

---

**The OpenCut web client enables automatic scroll restoration by setting `scrollRestoration: true` when creating the TanStack Router instance in [`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx), allowing the single-page application to mimic native browser back/forward scroll behavior.**

The OpenCut repository utilizes **TanStack Router** (the modern successor to React Router) to handle client-side navigation in its web application. By configuring a single boolean flag during router initialization, the application preserves user scroll positions across route changes, eliminating the need for custom scroll management code while maintaining consistency between server-side rendering and client hydration.

## How Scroll Restoration Works in OpenCut

The implementation relies on TanStack Router's built-in scroll manager, which activates automatically when the router is instantiated with the appropriate configuration. This system captures viewport offsets and restores them during history navigation without additional dependencies or manual event listeners.

### Router Configuration

In [`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx), the `getRouter()` function constructs the router instance using `createTanStackRouter` from `@tanstack/react-router`. The configuration object includes the `routeTree` imported from the auto-generated file and explicitly sets `scrollRestoration: true` to enable the feature globally.

```typescript
// apps/web/src/router.tsx
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

export function getRouter() {
  const router = createTanStackRouter({
    routeTree,
    scrollRestoration: true,   // ← enables automatic scroll restore
    defaultPreload: 'intent',
    defaultPreloadStaleTime: 0,
  });

  return router;
}

```

### Scroll Management Mechanics

When `scrollRestoration` is enabled, TanStack Router injects a scroll manager that records the scroll offset of each route upon navigation away. On subsequent visits—whether through browser back/forward buttons or programmatic navigation—the manager retrieves the saved offset and restores the viewport position before rendering completes. This logic handles edge cases including hash navigation, nested routes, and browser history navigation automatically, executing consistently during both client-side navigation and server-side rendering hydration.

## Configuring Scroll Behavior

While the global setting applies to all routes by default, OpenCut supports granular control through per-route overrides and imperative APIs for specific interaction patterns.

### Disabling Restoration for Specific Routes

For pages like infinite-scroll feeds where restoring previous positions creates poor user experience, override the default behavior by setting `scrollRestoration: false` in the route definition.

```typescript
// apps/web/src/routes/feed.tsx
import { createFileRoute } from '@tanstack/react-router';

export const Route = createFileRoute('/feed')({
  component: FeedPage,
  // Turn off restoration only for this route
  scrollRestoration: false,
});

```

### Manual Scroll Reset

To programmatically scroll to the top regardless of saved history, components can access the router instance via `useRouter` and invoke the `resetScroll()` method.

```typescript
import { useRouter } from '@tanstack/react-router';
import { useEffect } from 'react';

export function SomePage() {
  const router = useRouter();

  useEffect(() => {
    // Force scroll to top when this page mounts
    router.resetScroll();
  }, [router]);

  return <div>…</div>;
}

```

## Key Source Files

Several files define the scroll restoration architecture in the OpenCut codebase:

- **[`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx)**: Creates the TanStack Router instance with `scrollRestoration: true` enabled globally in the `getRouter()` function.
- **[`apps/web/src/routeTree.gen.ts`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routeTree.gen.ts)**: Auto-generated route tree consumed by the router configuration to build the navigation structure.
- **[`apps/web/src/routes/__root.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routes/__root.tsx)**: Root route definition that includes development tools for inspecting scroll behavior and router state.
- **[`apps/web/src/routes/index.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routes/index.tsx)**: Standard page route inheriting global scroll restoration settings from the router configuration.

## Summary

- OpenCut uses **TanStack Router** with `scrollRestoration: true` configured in [`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx) to enable automatic scroll position preservation across navigation events.
- The **scroll manager** automatically records and restores viewport offsets during back/forward navigation without requiring custom event listeners or state management.
- Developers can **disable restoration** for individual routes by setting `scrollRestoration: false` in the route configuration object, useful for infinite-scroll feeds or dynamic content.
- The **imperative API** via `router.resetScroll()` allows components to force scroll-to-top behavior regardless of saved history state.
- The implementation works consistently across **client-side navigation** and **SSR hydration** phases, ensuring uniform behavior for all users.

## Frequently Asked Questions

### Does OpenCut use React Router or TanStack Router for scroll restoration?

The OpenCut web application uses **TanStack Router**, configured in [`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx) with the `scrollRestoration: true` option to handle scroll position management automatically. TanStack Router is the modern successor to React Router and provides this functionality as a built-in configuration option rather than requiring separate packages or manual implementation.

### How do I disable scroll restoration for a specific page in OpenCut?

Set `scrollRestoration: false` in the route configuration object when defining the file route using `createFileRoute`. This overrides the global setting from [`router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/router.tsx) for that specific path, preventing the router from restoring previous scroll positions when users navigate back to this route, which is particularly useful for feeds or dynamically updating lists.

### Can I programmatically scroll to the top of the page in OpenCut?

Yes. Import `useRouter` from `@tanstack/react-router` and call `router.resetScroll()` inside a `useEffect` hook or event handler. This method forces the viewport to the top regardless of any saved scroll position in the browser history, allowing components to control scrolling behavior imperatively when needed.

### Where is the scroll restoration configured in the OpenCut codebase?

The global configuration resides in [`apps/web/src/router.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/router.tsx) within the `getRouter()` function, where `createTanStackRouter` receives the `scrollRestoration: true` parameter alongside the `routeTree`. Individual routes can override this setting in their respective route definition files, such as [`apps/web/src/routes/feed.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routes/feed.tsx) for route-specific behavior.