@riogz/router-plugin-persistent-params
A router plugin that maintains persistent parameters across route transitions, making them "sticky" throughout the navigation session.
Installation
npm install @riogz/router-plugin-persistent-params
Overview
This plugin ensures that specified parameters are automatically included in all route transitions. It's particularly useful for maintaining user preferences, theme settings, locale information, or debug flags across your entire application.
Quick Start
import { createRouter } from '@riogz/router'
import persistentParamsPlugin from '@riogz/router-plugin-persistent-params'
const router = createRouter([
{ name: 'home', path: '/' },
{ name: 'profile', path: '/profile/:userId' },
{ name: 'settings', path: '/settings' }
])
router.usePlugin(persistentParamsPlugin(['theme', 'locale']))
router.start()
router.navigate('profile', { userId: '123', theme: 'dark' })
router.navigate('settings')
API Reference
persistentParamsPlugin(config)
Creates a persistent parameters plugin factory.
Parameters
- config (
PersistentParamsConfig): Configuration for persistent parameters
string[]: Array of parameter names (parameters start as undefined)
Record<string, any>: Object with parameter names as keys and default values
Returns
PluginFactory: A plugin factory function for use with router.usePlugin()
Configuration Options
Array Format
When using an array, parameters will be undefined initially and only become persistent when first set during navigation.
router.usePlugin(persistentParamsPlugin(['theme', 'locale', 'debug']))
router.navigate('home')
router.navigate('profile', { userId: '123', theme: 'dark' })
router.navigate('settings')
Object Format
When using an object, parameters have default values and are included in all routes from the start.
router.usePlugin(persistentParamsPlugin({
theme: 'light',
locale: 'en',
debug: false
}))
router.navigate('home')
router.navigate('profile', { userId: '123', theme: 'dark' })
Common Use Cases
Theme Persistence
router.usePlugin(persistentParamsPlugin({ theme: 'auto' }))
function toggleTheme() {
const currentRoute = router.getState()
const newTheme = currentRoute.params.theme === 'dark' ? 'light' : 'dark'
router.navigate(currentRoute.name, {
...currentRoute.params,
theme: newTheme
})
}
Internationalization
router.usePlugin(persistentParamsPlugin({ locale: 'en' }))
function setLanguage(locale: string) {
const currentRoute = router.getState()
router.navigate(currentRoute.name, {
...currentRoute.params,
locale
})
}
Debug Flags
router.usePlugin(persistentParamsPlugin({
debug: process.env.NODE_ENV === 'development',
verbose: false,
showGrid: false
}))
router.navigate('current-route', { debug: true })
User Preferences
router.usePlugin(persistentParamsPlugin([
'sortBy',
'filterBy',
'viewMode',
'pageSize'
]))
router.navigate('products', {
sortBy: 'price',
filterBy: 'electronics',
viewMode: 'grid',
pageSize: '20'
})
router.navigate('categories')
How It Works
The plugin operates by:
- Modifying the root path: Adds persistent parameters as query parameters to the router's root path
- Decorating navigation methods: Automatically merges persistent parameters into
buildPath and buildState calls
- Listening to transitions: Updates persistent parameter values when they change during successful transitions
Internal Behavior
router.navigate('profile', { userId: '123' })
router.navigate('profile', { userId: '123' })
router.navigate('profile', { userId: '123', theme: 'dark' })
router.navigate('settings')
TypeScript Support
The plugin includes full TypeScript definitions:
import persistentParamsPlugin, {
PersistentParamsConfig,
persistentParamsPluginFactory
} from '@riogz/router-plugin-persistent-params'
const config: PersistentParamsConfig = {
theme: 'light' as 'light' | 'dark',
locale: 'en' as string,
debug: false as boolean
}
router.usePlugin(persistentParamsPlugin(config))
Integration Examples
React Integration
import { useRouter } from '@riogz/react-router'
export function useTheme() {
const router = useRouter()
const state = router.getState()
const setTheme = (theme: string) => {
router.navigate(state.name, {
...state.params,
theme
})
}
return {
theme: state.params.theme || 'light',
setTheme
}
}
import { useTheme } from '../hooks/useTheme'
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
{theme === 'dark' ? '☀️' : '🌙'}
</button>
)
}
URL Synchronization
router.usePlugin(persistentParamsPlugin({
theme: localStorage.getItem('theme') || 'light'
}))
router.subscribe((toState) => {
if (toState.params.theme) {
localStorage.setItem('theme', toState.params.theme)
}
})
Best Practices
Parameter Naming
Use descriptive, consistent parameter names:
router.usePlugin(persistentParamsPlugin([
'uiTheme',
'userLocale',
'debugMode'
]))
router.usePlugin(persistentParamsPlugin([
't',
'l',
'd'
]))
Default Values
Provide sensible defaults for better UX:
router.usePlugin(persistentParamsPlugin({
theme: 'light',
locale: navigator.language.split('-')[0] || 'en',
animations: true
}))
router.usePlugin(persistentParamsPlugin(['theme', 'locale']))
Performance Considerations
- Limit the number of persistent parameters (recommended: < 10)
- Use simple values (strings, numbers, booleans) rather than complex objects
- Consider URL length limitations for many parameters
Troubleshooting
Parameters Not Persisting
Ensure the plugin is registered before starting the router:
router.usePlugin(persistentParamsPlugin(['theme']))
router.start()
router.start()
router.usePlugin(persistentParamsPlugin(['theme']))
URL Too Long
If you have many persistent parameters, consider using shorter names or storing complex state in localStorage:
router.usePlugin(persistentParamsPlugin({
sessionId: generateSessionId()
}))
License
MIT
Contributing
Issues and pull requests are welcome on GitHub.