Quick start
One provider file, plus one edit to the layout you already have, and your first page transition runs.
One package per framework. This quick start uses React and Next.js; the equivalent setup for every other stack is in Frameworks.
Next.js App Router setup
One provider file, plus one edit to your layout. The route boundary is included.
Create the provider
One rule is enough to start:
drill()everywhere except the home route. It is the most visible transition, which makes step 4 unambiguous.// app/ssgoi-provider.tsx "use client"; import { type ReactNode } from "react"; import { Ssgoi } from "@ssgoi/react"; import { drill } from "@ssgoi/react/view-transitions"; const config = { transitions: [{ on: "/**", except: "/", transition: drill() }], }; export function SsgoiProvider({ children }: { children: ReactNode }) { return <Ssgoi config={config}>{children}</Ssgoi>; }The provider and shipped boundary are client components. SSGOI reads and moves real DOM nodes, and
usePathnameis read inside the shipped boundary. The pages passed into it can stay server components.transitionsalso accepts a function of device context — the usual way to give phones and desktops different motion.import { drill, fade } from "@ssgoi/react/view-transitions"; const config = { transitions: ({ isMobile }) => isMobile ? [{ on: "/**", except: "/", transition: drill() }] : [{ priority: -100, on: "/**", transition: fade() }], };prioritydefaults to 0, so-100parks that rule below every other one as a last resort — Route rules has the rest of the resolution order.isMobileis true when the scroll container is narrower than 768px, re-measured when it resizes. SSGOI calls your function once perisMobilevalue and caches the result, so keep it pure.Define
configoutside the component. A new object on every render rebuilds the engine and loses its saved scroll positions.Import the route boundary
The
keyis what makes the framework throw the old page away — SSGOI reacts to the framework destroying and rebuilding the routed node.data-ssgoi-transitionis just the label your rules match against.import { SsgoiRouteBoundary } from "@ssgoi/react/nextjs"; <SsgoiRouteBoundary>{children}</SsgoiRouteBoundary>Next.js is an optional peer, loaded only by this subpath. If the wrong part of the screen moves, adjust the boundary lifetime — Route boundaries shows how to move it up or down the tree.
Assemble them in the layout
This is the one edit to a file you already have. The element around
<Ssgoi>needs three classes; they hold the leaving page in place while it animates out.// app/layout.tsx import { type ReactNode } from "react"; import { SsgoiProvider } from "./ssgoi-provider"; import { SsgoiRouteBoundary } from "@ssgoi/react/nextjs"; export default function RootLayout({ children }: { children: ReactNode }) { return ( <html lang="en"> <body> <main className="relative z-0 min-h-dvh overflow-x-clip"> <SsgoiProvider> <SsgoiRouteBoundary>{children}</SsgoiRouteBoundary> </SsgoiProvider> </main> </body> </html> ); }Class Why it is there relativeThe leaving page is put back into the DOM with position: absolute, so it lands relative to the nearest positioned ancestor. Without this it jumps to the top of the document. z-0Gives the wrapper its own stacking context, so the layers a transition creates stay inside your shell instead of covering a fixed header. Transitions never use a negative z-index, so the leaving page cannot fall behind your background. overflow-x-clipStops a horizontal scrollbar from flashing while slide, drill or strip move a page off-screen. Use clip, not hidden — overflow-x: hidden turns the wrapper into the scroll container, and scroll restore then targets the wrong element. Without Tailwind, write
position: relative; z-index: 0; min-height: 100dvh; overflow-x: clip. If the leaving page appears in the wrong place or slides under your header, Layout shell explains which of the three is missing.Run it
Start the app and navigate. Two things tell you the wiring is right.
- From / to any other page, the new page slides in from the right.
- Back to /, the page slides out to the right.
If nothing moves, or the wrong region moves, the cause is almost in the layout or boundary placement: check Layout shell for the wrapper classes and Route boundaries for where the key sits.
That is the whole setup. This boundary remounts the entire routed area on every navigation, which is correct until you need something to stay put — a bottom nav that survives page changes, for instance. That is Persistent layouts.
Reference templates
Each template is a runnable app already wired the recommended way for its router. Clone one and read its provider, boundary and layout files, or copy the pieces you need.
Router integrations other than Next.js are experimental APIs.
Router helpers are grouped under their rendering framework. Qwik keeps the key and marker on the page root; Angular offers a structural directive that recreates that root when its key changes. All templates ↗
Next: pick the motion your product actually needs in Transitions.