JSPM

@zapstra/core-router

3.1.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 6
    • Score
      100M100P100Q74474F
    • License MIT

    Query-preserving router for Zapstra platform apps

    Package Exports

    • @zapstra/core-router

    Readme

    @zapstra/core-router

    Query-preserving router and navigation utilities for Zapstra platform apps.

    Features

    • Query parameter preservation during navigation (essential for Shopify apps)
    • Built-in loading states and progress indicators
    • React context for navigation state management
    • TypeScript support with full type safety
    • Customizable loading spinner with gradient design
    • Path matching utilities for active state detection

    Installation

    npm install @zapstra/core-router

    Usage

    Basic Setup

    import { AppRouterProvider } from '@zapstra/core-router';
    
    export default function App() {
      return (
        <AppRouterProvider>
          {/* Your app content */}
        </AppRouterProvider>
      );
    }
    import { useAppRouter } from '@zapstra/core-router';
    
    function NavigationComponent() {
      const { route, isNavigating } = useAppRouter();
    
      const handleNavigate = () => {
        // Automatically preserves ?host, ?shop, and other query params
        route('/app/settings');
      };
    
      return (
        <button
          onClick={handleNavigate}
          disabled={isNavigating}
        >
          Go to Settings
        </button>
      );
    }

    Direct Navigation Utilities

    import { useNavigateWithQuery, useQueryParams, useIsPathActive } from '@zapstra/core-router';
    
    function MyComponent() {
      const navigate = useNavigateWithQuery();
      const queryParams = useQueryParams();
      const isActive = useIsPathActive();
    
      // Navigate preserving query params
      const goToHome = () => navigate('/app');
    
      // Access current query parameters
      const shopDomain = queryParams.shop;
      const host = queryParams.host;
    
      // Check if path is active
      const isSettingsActive = isActive('/app/settings');
      const isExactHome = isActive('/app', true); // exact match
    
      return (
        <div>
          <button onClick={goToHome}>Home</button>
          <p>Current shop: {shopDomain}</p>
          <p>Settings active: {isSettingsActive}</p>
        </div>
      );
    }

    Custom Loading Spinner

    import { AppRouterProvider } from '@zapstra/core-router';
    
    export default function App() {
      return (
        <AppRouterProvider
          showLoadingSpinner={true}
          spinnerProps={{
            size: 100,
            strokeWidth: 6
          }}
        >
          {/* Your app */}
        </AppRouterProvider>
      );
    }

    Without Built-in Spinner

    import { AppRouterProvider, useAppRouter, GradientProgressSpinner } from '@zapstra/core-router';
    
    function CustomLoadingWrapper({ children }) {
      const { isNavigating } = useAppRouter();
    
      return (
        <>
          {isNavigating && <div>Custom loading...</div>}
          {children}
        </>
      );
    }
    
    export default function App() {
      return (
        <AppRouterProvider showLoadingSpinner={false}>
          <CustomLoadingWrapper>
            {/* Your app */}
          </CustomLoadingWrapper>
        </AppRouterProvider>
      );
    }

    Higher-Order Component

    import { withAppRouter } from '@zapstra/core-router';
    
    function MyApp() {
      return <div>My App Content</div>;
    }
    
    export default withAppRouter(MyApp, {
      showLoadingSpinner: true,
      spinnerProps: { size: 80 }
    });

    Why Query Preservation?

    Shopify apps run in embedded iframes and require specific query parameters like ?host and ?shop to function correctly. Standard navigation can lose these parameters, breaking the app. This router automatically preserves all query parameters during navigation.

    // Without @zapstra/core-router - BREAKS SHOPIFY APPS
    navigate('/app/settings'); // Loses ?host=... and ?shop=...
    
    // With @zapstra/core-router - WORKS CORRECTLY
    const { route } = useAppRouter();
    route('/app/settings'); // Preserves ?host=... and ?shop=...

    API Reference

    Components

    AppRouterProvider

    Main provider component that wraps your app.

    Props:

    • children: ReactNode - Your app content
    • showLoadingSpinner?: boolean - Show built-in loading spinner (default: true)
    • spinnerProps?: object - Customize spinner appearance

    GradientProgressSpinner

    Standalone loading spinner component.

    Props:

    • isLoading: boolean - Whether to show spinner
    • size?: number - Spinner size in pixels (default: 80)
    • strokeWidth?: number - Stroke width (default: 4)

    Hooks

    useAppRouter()

    Main navigation hook.

    Returns:

    • route: (path: string) => void - Navigate function with query preservation
    • isNavigating: boolean - Current navigation state

    useNavigateWithQuery()

    Low-level navigation hook.

    Returns:

    • (path: string) => void - Navigate function with query preservation

    useQueryParams()

    Get current query parameters as object.

    Returns:

    • Record<string, string> - Current query parameters

    useIsPathActive()

    Check if paths are active.

    Returns:

    • (path: string, exact?: boolean) => boolean - Path matching function

    Utilities

    Navigate while preserving query parameters.

    withAppRouter(Component, options?)

    Higher-order component to wrap apps with router provider.