Page Transitions
Route-based page transition system
Configuration Interface
SsgoiConfig
interface SsgoiConfig {
transitions: Array<{
from: string; // Source route pattern
to: string; // Destination route pattern
transition: SggoiTransition;
symmetric?: boolean; // Auto-generate bidirectional transition
}>;
defaultTransition?: SggoiTransition;
}
Basic Configuration
import { Ssgoi } from "@ssgoi/react";
import { fade, slide } from "@ssgoi/react/view-transitions";
const config = {
defaultTransition: fade(),
transitions: [
{ from: "/", to: "/about", transition: slide({ direction: "left" }) },
{ from: "/about", to: "/", transition: slide({ direction: "right" }) },
],
};
<Ssgoi config={config}>{children}</Ssgoi>;
Route Matching Rules
Pattern Types
- Exact Match:
/home
→ Matches exactly with/home
- Wildcard Suffix:
/products/*
→ Matches/products/123
- Full Wildcard:
*
→ Matches all routes
Matching Priority
More specific patterns take precedence:
transitions: [
// 1st priority: Exact match
{ from: "/blog/post-1", to: "/blog/post-2", transition: slide() },
// 2nd priority: Wildcard match
{ from: "/blog/*", to: "/blog/*", transition: fade() },
// 3rd priority: defaultTransition
];
Symmetric Option
Automatically generates bidirectional transitions:
{
from: '/home',
to: '/about',
transition: fade(),
symmetric: true // Automatically generates reverse transition
}
// The above configuration works as follows:
// /home → /about: fade
// /about → /home: fade (auto-generated)
View Transition Structure
View Transition follows the same structure as Element Transition:
interface ViewTransition {
in?: (
element: HTMLElement,
context?: SggoiTransitionContext
) => TransitionConfig;
out?: (
element: HTMLElement,
context?: SggoiTransitionContext
) => TransitionConfig;
}
- out: Applied to from page (exiting page)
- in: Applied to to page (entering page)
Context Object
The scroll difference between the previous page and current page is passed as the second argument to View Transition:
interface SggoiTransitionContext {
scrollOffset: {
x: number; // Scroll X difference between previous and current page
y: number; // Scroll Y difference between previous and current page
};
}
// Example: Scroll-aware transition
const scrollAwareTransition = {
in: (element, context) => {
const { scrollOffset } = context;
return {
prepare: (el) => {
// Start by moving by the scroll difference
el.style.transform = `translateY(${-scrollOffset.y}px)`;
},
tick: (progress) => ({
// Return to original position
transform: `translateY(${-scrollOffset.y * (1 - progress)}px)`,
}),
};
},
};
SsgoiTransition Component
Wrapper component that wraps each page:
<SsgoiTransition id="/page-path">
<PageContent />
</SsgoiTransition>
id
: Identifier used for route matching- This ID is matched against from/to patterns in config
Operation Flow
- Route Change Detection: Router changes route
- Pattern Matching: Find transition to apply using from/to patterns
- Out Animation: Apply out transition to current page
- Synchronization: Wait for out and in animation preparation
- In Animation: Apply in transition to new page
- Completion: Clean up when both animations complete
Practical Examples
Hierarchical Navigation
const config = {
transitions: [
// List → Detail
{
from: "/products",
to: "/products/*",
transition: scale({ from: 0.95 }),
symmetric: true, // Auto-handle Detail → List too
},
// Tab navigation
{ from: "/tab1", to: "/tab2", transition: slide({ direction: "left" }) },
{ from: "/tab2", to: "/tab3", transition: slide({ direction: "left" }) },
{ from: "/tab3", to: "/tab2", transition: slide({ direction: "right" }) },
{ from: "/tab2", to: "/tab1", transition: slide({ direction: "right" }) },
],
};