-
Notifications
You must be signed in to change notification settings - Fork 168
Description
Describe the feature
Motivation
Currently, unstorage provides excellent support for various storage backends including localStorage, sessionStorage,
memory, and numerous cloud providers. However, there's a missing piece for browser-based applications that need to
persist lightweight state in URLs - a query string driver.
This driver would be invaluable for:
- Shareable State: Store application state directly in the URL, making it easily shareable via links
- Bookmarkable Views: Enable users to bookmark specific application states (filters, search params, view preferences)
- Back/Forward Navigation: Leverage browser history for state management without additional complexity
- Server-Side Rendering: Access state on the server during SSR without cookies or sessions
- Analytics & Tracking: URL parameters are automatically captured by most analytics tools
- Zero-Dependency State: No external storage required - the URL itself is the storage medium
Use Cases
- E-commerce filters (price range, categories, sorting)
- Search interfaces with complex query builders
- Dashboard configurations and view settings
- Form wizards with step state
- Data table pagination and sorting preferences
- Feature flags and A/B testing parameters
Implementation Plan
- Driver Specification
interface QueryStringOptions {
/**
* Base URL or window.location to use
* @default window?.location
*/
url?: URL | Location;
/**
* Prefix for all keys to avoid conflicts
* @default ""
*/
base?: string;
/**
* Whether to update browser history
* @default true
*/
updateHistory?: boolean;
/**
* History update method
* @default "replaceState"
*/
historyMethod?: "pushState" | "replaceState";
/**
* Custom serializer for complex values
*/
serializer?: {
serialize: (value: any) => string;
deserialize: (value: string) => any;
};
/**
* Window object for browser environments
*/
window?: Window;
}
- Core Implementation
The driver will implement the standard Driver interface with these key behaviors:
- Storage: Use URLSearchParams API for robust query string manipulation
- Key Normalization: Convert unstorage keys to URL-safe parameter names
- Value Serialization: JSON stringify/parse for complex objects, with fallback to string values
- Browser Integration: Optional history API integration for seamless navigation
- SSR Support: Work with both browser Location and Node.js URL objects
- Method Implementations
// Pseudo-code structure
export default defineDriver((opts: QueryStringOptions = {}) => {
const getSearchParams = () => new URLSearchParams(opts.url?.search || "");
const updateURL = (params: URLSearchParams) => {
// Update URL with new params
// Optionally update browser history
};
return {
name: "query-string",
hasItem(key) {
return getSearchParams().has(normalizeKey(key));
},
getItem(key) {
const value = getSearchParams().get(normalizeKey(key));
return value ? deserialize(value) : null;
},
setItem(key, value) {
const params = getSearchParams();
params.set(normalizeKey(key), serialize(value));
updateURL(params);
},
removeItem(key) {
const params = getSearchParams();
params.delete(normalizeKey(key));
updateURL(params);
},
getKeys() {
return Array.from(getSearchParams().keys());
},
clear() {
updateURL(new URLSearchParams());
},
watch(callback) {
// Listen to popstate events for browser navigation
}
};
});
- Special Considerations
- URL Length Limits: Add option to warn/error when approaching browser URL limits (~2000 chars)
- Value Encoding: Proper encoding/decoding for special characters
- Array Values: Support for repeated parameters (e.g., ?tag=a&tag=b)
- Nested Objects: Flatten nested structures or use bracket notation
- Performance: Debounce URL updates to avoid excessive history entries
Testing Strategy
- Unit tests for all driver methods
- Browser environment tests with history API
- SSR compatibility tests with Node.js URL
- Edge cases: special characters, large values, concurrent updates
- Integration tests with unstorage mounting system
Documentation Requirements
- Basic usage examples
- Browser vs SSR configuration
- Best practices for URL-safe keys
- Performance considerations
- Migration guide from other state management solutions
Backwards Compatibility
This is a new driver addition with no breaking changes to existing functionality.
Alternative Approaches Considered
- Using hash fragments (#key=value) - Limited browser support and conflicts with routing
- Cookie driver enhancement - Cookies have different use cases and limitations
- External library wrapper - Native implementation provides better integration
References
- URLSearchParams API: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
- History API: https://developer.mozilla.org/en-US/docs/Web/API/History_API
- Similar implementations:
- React Router's useSearchParams
- Vue Router's query handling
- Nuxt's useState with URL persistence
This driver would be a valuable addition to unstorage's already comprehensive driver ecosystem, filling a gap in
URL-based state persistence that many modern web applications require.
Additional information
- Would you be willing to help implement this feature?