npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@groundbrick/sveltekit-adapter

v0.2.4

Published

SvelteKit integration adapter with API client, stores, hooks, analytics, and cookie consent system

Readme

@groundbrick/sveltekit-adapter

SvelteKit integration adapter para o microframework TypeScript - fornece integração client-side com APIs Express, gerenciamento de estado reativo, autenticação JWT, hooks e sistema de consentimento de cookies.

Features Implementadas

  • 🔧 ApiClient - Cliente HTTP com autenticação, retry, timeout e suporte a cookies
  • 🔐 Gerenciamento de Autenticação - Autenticação segura usando HttpOnly cookies
  • 📊 Stores Reativas - Stores Svelte para estado de auth e API com suporte a runes
  • � Sistema de Notificações - Sistema completo de notificações toast com auto-clear na navegação
  • �🛡️ Error Handling - Hooks abrangentes de tratamento de erros
  • 📝 Request Logging - Log automático de request/response com timing
  • 🎣 SvelteKit Hooks - Hooks pré-construídos para autenticação e logging
  • 🔄 Retry Logic - Lógica de retry automática com exponential backoff
  • ⏱️ Timeout Handling - Controle de timeout configurável para requests
  • 🍪 Cookie Consent - Sistema GDPR-compliant de consentimento com Google Analytics

Instalação

npm install @groundbrick/sveltekit-adapter

Peer Dependencies

npm install @sveltejs/kit svelte

Quick Start

1. Configuração de Hooks

// src/hooks.server.ts
import { sequence } from '@sveltejs/kit/hooks';
import { createSvelteKitHooks } from '@groundbrick/sveltekit-adapter';

const { hooks, handleError } = createSvelteKitHooks({
  logger: {
    logRequests: true,
    logResponses: true,
    includeHeaders: false,
    excludePaths: ['/favicon.ico', '/robots.txt', '/health'],
    context: 'my-app'
  },
  auth: {
    tokenKey: 'auth_token',
    publicPaths: ['/login', '/register', '/', '/api/public/*'],
    redirectPath: '/login',
    onAuthRequired: () => {
      console.log('Authentication required');
    }
  },
  errorHandler: {
    logErrors: true,
    context: 'my-app',
    onError: (error, context) => {
      // Custom error handling
      console.error('App error:', error, context);
    }
  }
});

export const handle = sequence(...hooks);
export { handleError };

2. Configuração do API Client

// src/lib/api.ts
import { createApiClient } from '@groundbrick/sveltekit-adapter';

export const apiClient = createApiClient({
  baseUrl: 'http://localhost:3000/api',
  timeout: 10000,
  retries: 3,
  defaultHeaders: {
    'X-App-Version': '1.0.0',
    'X-Client': 'sveltekit'
  }
});

3. Cookie Consent Setup

// src/routes/+layout.svelte
<script lang="ts">
  import { 
    CookieConsent, 
    ConsentService,
    createConsentAwareAnalytics 
  } from '@groundbrick/sveltekit-adapter/consent';

  // Initialize consent service
  const consentService = ConsentService.getInstance();
  
  // Setup analytics with consent awareness
  const analytics = createConsentAwareAnalytics(consentService, {
    gaId: 'G-XXXXXXXXXX',
    enableDebug: true
  });
</script>

<!-- Your app content -->
<slot />

<!-- Cookie consent banner -->
<CookieConsent 
  theme="light"
  position="bottom"
  onConsentChange={(state) => {
    console.log('Consent updated:', state);
  }}
/>

4. Using Stores

// src/routes/+page.svelte
<script lang="ts">
  import { 
    authStore, 
    apiStore, 
    isAuthenticated, 
    currentUser,
    initializeStores 
  } from '@groundbrick/sveltekit-adapter';

  // Initialize stores on app start
  initializeStores();

  // Reactive to authentication state
  $: if ($isAuthenticated) {
    console.log('User is logged in:', $currentUser);
  }
</script>

{#if $isAuthenticated}
  <h1>Welcome, {$currentUser?.name}!</h1>
{:else}
  <a href="/login">Please log in</a>
{/if}

{#if $apiStore.loading}
  <div class="spinner">Loading...</div>
{/if}

{#if $apiStore.error}
  <div class="error">{$apiStore.error}</div>
{/if}

Module Exports

Main Package

// Everything from client and hooks
import { 
  createApiClient, 
  authStore, 
  createSvelteKitHooks 
} from '@groundbrick/sveltekit-adapter';

Client Module

// Just client functionality
import { 
  ApiClient, 
  createApiClient,
  authStore,
  apiStore,
  isAuthenticated,
  currentUser,
  isLoading,
  currentError,
  initializeStores,
  clearErrors
} from '@groundbrick/sveltekit-adapter/client';

Hooks Module

// Just hooks functionality
import { 
  createSvelteKitHooks,
  createAuthHook,
  createLoggerHook,
  createErrorHandlerHook
} from '@groundbrick/sveltekit-adapter/hooks';

Consent Module

// Cookie consent system
import { 
  CookieConsent,
  ConsentService,
  createConsentAwareAnalytics,
  GDPR_CONFIG,
  CCPA_CONFIG
} from '@groundbrick/sveltekit-adapter/consent';

API Client Features

Basic Usage

import { createApiClient } from '@groundbrick/sveltekit-adapter';

const client = createApiClient({
  baseUrl: 'https://api.example.com',
  timeout: 10000,
  retries: 3
});

// GET request
const users = await client.get('/users');

// POST request with data
const newUser = await client.post('/users', {
  name: 'John Doe',
  email: '[email protected]'
});

// Request with auth token
const profile = await client.get('/profile', {
  headers: { Authorization: 'Bearer token' }
});

Advanced Configuration

const client = createApiClient({
  baseUrl: 'https://api.example.com',
  timeout: 15000,
  retries: 5,
  retryDelay: 1000,
  defaultHeaders: {
    'Content-Type': 'application/json',
    'X-API-Version': '2024-01-01'
  },
  interceptors: {
    request: (config) => {
      // Add timestamp to all requests
      config.headers['X-Timestamp'] = new Date().toISOString();
      return config;
    },
    response: (response) => {
      // Log all successful responses
      console.log('Response received:', response.status);
      return response;
    },
    error: (error) => {
      // Custom error handling
      if (error.status === 401) {
        // Redirect to login
        window.location.href = '/login';
      }
      throw error;
    }
  }
});

Authentication Flow

The adapter provides secure authentication using HttpOnly cookies:

How Authentication Works:

  1. Server-side: Auth hook validates JWT tokens from HttpOnly cookies (no client-side token handling)
  2. Client-side: API Client automatically includes cookies with all requests
  3. Automatic cleanup: Invalid tokens are cleared through HttpOnly cookie management
  4. Smart redirects: Users are redirected to login with current page as return URL
  5. No performance impact: No unnecessary API calls on page loads

Auth Hook Configuration:

// src/hooks.server.ts
const { hooks, handleError } = createSvelteKitHooks({
  auth: {
    tokenKey: 'auth_token',
    redirectPath: '/login',
    publicPaths: [
      '/login',
      '/register', 
      '/',
      '/landing',
      '/api/*', // Allow API calls to pass through
      '/favicon.ico',
      '/robots.txt'
    ],
    validateExpiration: true // Enable JWT expiration checking (default: true)
  }
});

Cookie Consent System

GDPR Compliance

import { 
  ConsentService, 
  GDPR_CONFIG,
  createConsentAwareAnalytics 
} from '@groundbrick/sveltekit-adapter/consent';

// GDPR-compliant setup
const consentService = ConsentService.getInstance(GDPR_CONFIG);

// Analytics only loads with explicit consent
const analytics = createConsentAwareAnalytics(consentService, {
  gaId: 'G-XXXXXXXXXX',
  anonymizeIp: true
});

// Track events (respects consent automatically)
analytics.trackEvent({
  action: 'button_click',
  category: 'UI',
  label: 'signup'
});

Custom Configuration

const customConfig = {
  banner: {
    title: '🍪 Cookies',
    message: 'We use cookies to improve your experience.',
    acceptAllText: 'Accept All',
    rejectAllText: 'Reject All'
  },
  categories: {
    functional: {
      required: true,
      name: 'Essential',
      description: 'Required for basic functionality'
    },
    analytics: {
      required: false,
      name: 'Analytics',
      description: 'Help us improve our website'
    }
  }
};

const consentService = ConsentService.getInstance(customConfig);

Stores System

Authentication Store

import { authStore, isAuthenticated, currentUser } from '@groundbrick/sveltekit-adapter';

// Reactive authentication state
$: if ($isAuthenticated) {
  console.log('User:', $currentUser);
}

// Login
authStore.login({
  token: 'jwt-token',
  user: { id: 1, name: 'John', email: '[email protected]' }
});

// Logout
authStore.logout();

// Check if user has specific role
if ($currentUser?.roles?.includes('admin')) {
  // Show admin content
}

API Store

import { apiStore, isLoading, currentError } from '@groundbrick/sveltekit-adapter';

// Loading states
$: if ($isLoading) {
  // Show spinner
}

// Error handling
$: if ($currentError) {
  // Show error message
  console.error('API Error:', $currentError);
}

// Manual error clearing
apiStore.clearError();

Notification System

import { 
  showSuccess, 
  showError, 
  showWarning, 
  showInfo,
  clearAllNotifications,
  useNavigationNotificationClear 
} from '@groundbrick/sveltekit-adapter';

// Enable auto-clearing on navigation (add to your root layout)
useNavigationNotificationClear();

// Show different types of notifications
showSuccess('Data saved successfully!');
showError('Something went wrong!');
showWarning('This action cannot be undone!');
showInfo('New feature available!');

// With options
showSuccess('Operation complete!', {
  title: 'Success',
  duration: 3000,
  persistent: false // won't clear on navigation if true
});

// Clear notifications
clearAllNotifications();

Add notification component to your layout:

<script>
  import { useNavigationNotificationClear } from '@groundbrick/sveltekit-adapter';
  import Notifications from '$lib/components/Notifications.svelte';
  
  // Enable auto-clearing
  useNavigationNotificationClear();
</script>

<main>
  <slot />
</main>

<!-- Notifications -->
<Notifications />

Logging Estruturado

  • Request/Response: Log automático com timing
// Configuração no hooks.server.ts
const loggerHook = createLoggerHook({
  logRequests: true,   // GET /api/users [timing: 245ms]
  logResponses: true   // GET /api/users 200 OK [duration: 245ms]
});

// Logs automáticos no console/arquivo
// INFO: Incoming request { method: 'GET', url: '/api/users', duration: 245 }
  • Context preservation: Mantém contexto através da aplicação
// Contexto propagado automaticamente
const logger = createLogger().child('user-service');
// user-service: Processing user creation
// user-service: Database query completed
// user-service: User created successfully
  • Structured data: Logs estruturados com metadados
// Metadados automáticos em cada log
logger.info('User login', {
  userId: 123,
  ip: '192.168.1.1',
  userAgent: 'Chrome/120.0',
  timestamp: '2024-01-15T10:30:00Z',
  requestId: 'req_abc123'
});
  • Performance tracking: Tracking de performance automático
// Timing automático de requests
const startTime = Date.now();
await apiClient.get('/heavy-endpoint');
// Log: Request completed { duration: 1247ms, status: 200 }

// Timing de hooks
// Log: Request processed { url: '/dashboard', duration: 89ms }

Melhores Práticas

  1. Inicialize stores cedo no ciclo de vida da aplicação
  2. Use stores reativas em vez de gerenciamento manual de estado
  3. Configure hooks apropriadamente para as necessidades da sua aplicação
  4. Use TypeScript para melhor experiência de desenvolvimento
  5. Trate erros graciosamente com os error stores
  6. Configure paths públicos no hook de autenticação
  7. Use retry mechanism para endpoints instáveis
  8. Implemente consent desde o início para compliance
  9. Configure analytics com consent awareness
  10. Use presets de configuração para diferentes regiões

Compatibilidade

  • Svelte 5.x com runes support
  • SvelteKit 2.x com app directory structure
  • Node.js 18+ para funcionalidades de servidor
  • TypeScript 5.x para tipagem completa

Dependencies

Required

  • @groundbrick/logger - Sistema de logging

Peer Dependencies

  • @sveltejs/kit - SvelteKit framework (^2.0.0)
  • svelte - Svelte framework (^5.0.0)

License

MIT

Packaging & build notes

  • During the package build we copy some source assets (for example, .svelte components) from src/ into the published dist/ folder. This is handled by the script scripts/copy-assets.js which runs after tsc in the package build script.

  • Why: some modules are intentionally re-exported as source Svelte components (for example analytics/components/GoogleAnalytics.svelte). The compiled TypeScript output in dist contains runtime imports to those .svelte files. To make the package consumable by apps that will compile Svelte components in their own build (SvelteKit apps), we ship the .svelte files alongside the compiled JS so imports resolve correctly.

  • Why not rsync: earlier we used rsync to copy files, but that requires rsync to be present on the build server. To make builds portable across environments we now use a small cross-platform Node script.

  • Alternatives:

    • Precompile Svelte components into JavaScript during the package build (using Rollup/Vite or svelte/compiler). This produces a distribution with JS only (no .svelte sources), which is cleaner for non-Svelte consumers but requires adding a Svelte compilation step to the package build.
    • Keep shipping .svelte files (the current approach). This is the simplest and lets SvelteKit apps compile components during app build time.
  • If you prefer a precompiled distribution, open an issue or request and we can add a Rollup/Vite build step (low-risk, slightly larger change).