Context Flow in SSGOI
SSGOI uses Svelte’s context API to manage state and configuration across components. This guide explains how context flows through the library and how the different pieces work together.
Overview
SSGOI’s context system consists of four main contexts that work together:
- Config Context - Stores transition configuration
- Page Transition Context - Tracks navigation state
- Scroll History Context - Maintains scroll positions
- Hero Context - Manages hero animations
Context Flow Diagram
┌─────────────────────────────────────────────────────────┐
│ App Root (+layout) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ <Ssgoi> Component │ │
│ │ - Initializes all contexts │ │
│ │ - Sets up onNavigate hooks │ │
│ │ - Provides context to children │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Page Content (+page) │ │ │
│ │ │ ┌───────────────────────────────────────┐ │ │ │
│ │ │ │ <PageTransition> Component │ │ │ │
│ │ │ │ - Consumes contexts │ │ │ │
│ │ │ │ - Applies transitions │ │ │ │
│ │ │ │ - Wraps page content │ │ │ │
│ │ │ └───────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Initialization Phase
1. Setting Up the Provider (Ssgoi.svelte
)
<script lang="ts">
import context from '../context/index.js';
// Initialize all contexts
context.config.init(config);
const pageTransitionContext = context.pageTransition.init();
const scrollHistoryContext = context.scrollHistory.init();
context.hero.init();
// Set up navigation hooks
onNavigate(({ from, to }) => {
pageTransitionContext.from = from;
pageTransitionContext.to = to;
});
onNavigate(({ from }) => {
// Save scroll position before navigating away
const path = from?.url.pathname;
if (path) {
scrollHistoryContext[path] = document.scrollingElement?.scrollTop ?? 0;
}
});
</script>
The Ssgoi
component:
- Creates all four contexts and makes them available to child components
- Sets up navigation listeners to update context state
- Saves scroll positions before navigation
2. Configuration Setup
The configuration you provide determines which transitions are used:
// Example: page-config.ts
const config = createTransitionConfig({
transitions: [
{
from: '/products',
to: '/products/*',
transitions: transitions.hero()
},
{
from: '/posts',
to: '/posts/*',
transitions: transitions.fade()
}
],
defaultTransition: transitions.none()
});
This configuration is stored in the config context and accessed during navigation.
Runtime Phase
3. Navigation Trigger
When navigation occurs (user clicks a link):
- SvelteKit’s
onNavigate
fires - Page Transition Context is updated with
from
andto
routes - Scroll History Context saves the current scroll position
4. Transition Application (PageTransition.svelte
)
<script lang="ts">
// Get contexts
const config = context.config.get();
const scrollHistoryContext = context.scrollHistory.get();
const pageTransitionContext = context.pageTransition.get();
function transitionIn(node: HTMLElement, params) {
const { from, to } = pageTransitionContext;
// Config function determines which transition to use
const transition = config({ path: from.url.pathname }, { path: to.url.pathname });
return transition.in(node, params);
}
function transitionOut(node: HTMLElement, params) {
const { from, to } = pageTransitionContext;
const transition = config({ path: from.url.pathname }, { path: to.url.pathname });
return transition.out(node, params);
}
</script>
The PageTransition
component:
- Retrieves all contexts
- Uses the config to determine which transition to apply
- Passes scroll positions to transitions
- Applies enter/exit animations
Context Details
Config Context
Purpose: Stores the transition configuration function
Data Structure:
type ConfigContext = (from: RouteInfo, to: RouteInfo) => TransitionOption
Usage: Called during navigation to determine which transition to use based on the current and target routes.
Page Transition Context
Purpose: Tracks current navigation state
Data Structure:
type PageTransitionContext = {
from: Navigation['from'], // Previous route
to: Navigation['to'] // Target route
}
Usage: Updated on every navigation, consumed by PageTransition
to know which routes are transitioning.
Scroll History Context
Purpose: Maintains scroll positions for each visited route
Data Structure:
type ScrollHistoryContext = Record<string, number>
// Example: { '/': 0, '/products': 150, '/about': 300 }
Usage:
- Saves scroll position before navigation
- Provides scroll positions to transitions for smooth animations
- Enables scroll restoration when navigating back
Hero Context
Purpose: Provides crossfade functionality for hero transitions
Data Structure:
type HeroContext = {
send: Function, // Marks element as hero source
receive: Function // Marks element as hero target
}
Usage: Special context for hero animations that need to animate elements between different pages.
Example: Complete Flow
Let’s trace a navigation from /products
to /products/widget
:
User clicks a product link
onNavigate
fires inSsgoi.svelte
:pageTransitionContext.from = { url: { pathname: '/products' } } pageTransitionContext.to = { url: { pathname: '/products/widget' } } scrollHistoryContext['/products'] = 150 // Current scroll position
Old page starts exit transition:
PageTransition
callstransitionOut
- Config function returns
hero()
transition - Hero transition starts with saved scroll position
New page starts enter transition:
PageTransition
callstransitionIn
- Same
hero()
transition is applied - Elements animate to their new positions
Transitions complete:
- Navigation is finished
- Contexts are ready for next navigation
Best Practices
- Always wrap page content with
PageTransition
to enable transitions - Configure transitions thoughtfully - consider user experience and performance
- Use appropriate transitions - hero for detail views, fade for unrelated pages
- Test scroll behavior - ensure positions are saved and restored correctly
Custom Context Usage
You can access these contexts in your own components:
<script>
import { getContext } from 'svelte';
// Get the current navigation state
const pageTransition = getContext(Symbol.for('page-transition-navigation'));
// Access scroll history
const scrollHistory = getContext(Symbol.for('scroll-history'));
</script>
Note: Direct context access is rarely needed - the built-in components handle most use cases.
Summary
SSGOI’s context flow enables smooth page transitions by:
- Centralizing configuration in the config context
- Tracking navigation state in the page transition context
- Preserving scroll positions in the scroll history context
- Enabling complex animations with the hero context
The contexts work together seamlessly, with Ssgoi
setting up the system and PageTransition
consuming it to create beautiful transitions.