SvelteKit Integration Example
This example shows how to integrate the Asterisms JS SDK Backend with a SvelteKit application.
Complete Setup
1. Install Dependencies
npm install @asterisms/sdk-backend @asterisms/sdk @asterisms/common-core
2. Environment Configuration
Create .env file:
# Asterisms Configuration
ASTERISMS_DOMAIN=asterisms.example.com
ASTERISMS_BUNDLE_ID=com.example.myapp
ASTERISMS_SUBDOMAIN=myapp
ASTERISMS_NAME=My App
ASTERISMS_TITLE=My App
ASTERISMS_DESCRIPTION=My Asterisms Application
# Optional: Product Authorization Key
ASTERISMS_PRODUCT_AUTHORIZATION_KEY=your-product-key
3. SDK Instance Setup
Create src/lib/sdkInstance.ts:
import { createSvelteKitBackendSDK, type AsterismsSDKProvider } from '@asterisms/sdk-backend';
import { createFetchAdapter } from '@asterisms/sdk-backend';
import { building } from '$app/environment';
import * as dotenv from 'dotenv';
dotenv.config();
let provider: AsterismsSDKProvider | null = null;
export function useAsterismsBackendSDK(): AsterismsSDKProvider | undefined {
if (building) return undefined;
if (provider) return provider;
try {
provider = createSvelteKitBackendSDK({
env: process.env,
building,
httpFactory: createFetchAdapter(fetch),
registrationData: {
bundleId: 'com.example.myapp',
capabilities: ['FRONTEND_WEBSITE'],
description: 'My Asterisms Application',
name: 'My App',
subdomain: 'myapp',
title: 'My App',
icon: 'app',
group: 'apps'
}
});
return provider;
} catch (error) {
console.error('Failed to initialize Asterisms JS SDK:', error);
return undefined;
}
}
export function getSDK() {
const provider = useAsterismsBackendSDK();
return provider?.sdk;
}
4. Hooks Setup
Create or update src/hooks.server.ts:
import { useAsterismsBackendSDK } from '$lib/sdkInstance';
import type { Handle } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';
const asterismsHandle: Handle = async ({ event, resolve }) => {
const provider = useAsterismsBackendSDK();
if (provider) {
try {
// Boot the SDK
await provider.bootSDK();
// Make SDK available in locals
event.locals.sdk = provider.sdk;
// Handle Asterisms backend core API routes
if (event.url.pathname.startsWith('/api/asterisms')) {
return provider.apiRouter(event);
}
} catch (error) {
console.error('SDK boot error:', error);
}
}
return resolve(event);
};
const customHandle: Handle = async ({ event, resolve }) => {
// Your custom logic here
return resolve(event);
};
export const handle = sequence(asterismsHandle, customHandle);
5. TypeScript Definitions
Create or update src/app.d.ts:
import type { AsterismsBackendSDK } from '@asterisms/sdk-backend';
declare global {
namespace App {
interface Locals {
sdk?: AsterismsBackendSDK;
}
interface PageData {
user?: {
id: string;
name: string;
email: string;
};
}
}
}
export {};
6. API Routes
Create src/routes/api/user/+server.ts:
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ locals }) => {
try {
const sdk = locals.sdk;
if (!sdk) {
return json({ error: 'SDK not available' }, { status: 503 });
}
// Use authorization service
const auth = sdk.authorization();
const user = await auth.getCurrentUser();
return json({ user });
} catch (error) {
console.error('User API error:', error);
return json({ error: 'Failed to get user' }, { status: 500 });
}
};
export const POST: RequestHandler = async ({ request, locals }) => {
try {
const sdk = locals.sdk;
if (!sdk) {
return json({ error: 'SDK not available' }, { status: 503 });
}
const data = await request.json();
// Use storage service
const storage = sdk.storage();
await storage.set(`user-data-${data.userId}`, data);
return json({ success: true });
} catch (error) {
console.error('User data save error:', error);
return json({ error: 'Failed to save user data' }, { status: 500 });
}
};
7. Page Load Functions
Create src/routes/+layout.server.ts:
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async ({ locals }) => {
const sdk = locals.sdk;
if (!sdk) {
return {
user: null
};
}
try {
const auth = sdk.authorization();
const user = await auth.getCurrentUser();
return {
user: user
? {
id: user.id,
name: user.name,
email: user.email
}
: null
};
} catch (error) {
console.error('Layout load error:', error);
return {
user: null
};
}
};
8. Svelte Components
Create src/routes/+layout.svelte:
<script lang="ts">
import type { LayoutData } from './$types';
export let data: LayoutData;
$: user = data.user;
</script>
<div class="app">
<header>
<h1>My Asterisms App</h1>
{#if user}
<p>Welcome, {user.name}!</p>
{:else}
<p>Please log in</p>
{/if}
</header>
<main>
<slot />
</main>
</div>
<style>
.app {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
border-bottom: 1px solid #eee;
padding-bottom: 20px;
margin-bottom: 20px;
}
</style>
9. Dashboard Page
Create src/routes/dashboard/+page.server.ts:
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals }) => {
const sdk = locals.sdk;
if (!sdk) {
return {
notifications: [],
userData: null
};
}
try {
const auth = sdk.authorization();
const storage = sdk.storage();
const user = await auth.getCurrentUser();
if (!user) {
return {
notifications: [],
userData: null
};
}
// Get user data from storage
const userData = await storage.get(`user-data-${user.id}`);
return {
notifications: [],
userData
};
} catch (error) {
console.error('Dashboard load error:', error);
return {
notifications: [],
userData: null
};
}
};
Create src/routes/dashboard/+page.svelte:
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
let message = '';
let sending = false;
async function sendNotification() {
sending = true;
try {
const response = await fetch('/api/notifications', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Test Notification',
message: message
})
});
if (response.ok) {
message = '';
alert('Notification sent!');
} else {
alert('Failed to send notification');
}
} catch (error) {
console.error('Send notification error:', error);
alert('Error sending notification');
} finally {
sending = false;
}
}
</script>
<div class="dashboard">
<h2>Dashboard</h2>
{#if data.userData}
<div class="user-data">
<h3>User Data</h3>
<pre>{JSON.stringify(data.userData, null, 2)}</pre>
</div>
{/if}
<div class="notification-form">
<h3>Send Notification</h3>
<textarea
bind:value={message}
placeholder="Enter notification message..."
rows="3"
></textarea>
<button
on:click={sendNotification}
disabled={sending || !message.trim()}
>
{sending ? 'Sending...' : 'Send Notification'}
</button>
</div>
</div>
<style>
.dashboard {
max-width: 800px;
margin: 0 auto;
}
.user-data {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
.notification-form {
background: white;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
textarea {
width: 100%;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
</style>
10. Notification API
Create src/routes/api/notifications/+server.ts:
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const POST: RequestHandler = async ({ request, locals }) => {
try {
const sdk = locals.sdk;
if (!sdk) {
return json({ error: 'SDK not available' }, { status: 503 });
}
const { title, message } = await request.json();
if (!title || !message) {
return json({ error: 'Title and message are required' }, { status: 400 });
}
// Get current user
const auth = sdk.authorization();
const user = await auth.getCurrentUser();
if (!user) {
return json({ error: 'User not authenticated' }, { status: 401 });
}
// Send notification
const notifications = sdk.notifications();
await notifications.sendToUser(user.id, {
title,
message
});
return json({ success: true });
} catch (error) {
console.error('Notification API error:', error);
return json({ error: 'Failed to send notification' }, { status: 500 });
}
};
Package.json Scripts
Add these scripts to your package.json:
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint .",
"format": "prettier --write ."
}
}
Running the Application
-
Install dependencies:
-
Configure environment variables in .env
-
Start development server:
-
Visit http://localhost:5173
Key Features Demonstrated
✅ SDK Integration
- Proper SvelteKit integration with
createSvelteKitBackendSDK
- Environment-based configuration
- Graceful handling of build-time vs runtime
✅ Authentication
- User authentication through authorization service
- Protected API routes
- User data in page loads
✅ Storage
- Storing and retrieving user data
- Async storage operations
- Error handling
✅ Notifications
- Sending notifications to users
- API endpoint for notifications
- Frontend integration
✅ Error Handling
- Comprehensive error handling
- User-friendly error messages
- Graceful fallbacks
Production Considerations
Security
- Use HTTPS in production
- Validate all user inputs
- Implement proper rate limiting
- Use secure environment variables
Performance
- Implement caching strategies
- Use database connections efficiently
- Monitor SDK performance
- Optimize bundle sizes
Monitoring
- Add structured logging
- Monitor API endpoints
- Track user interactions
- Set up error tracking
Next Steps
- Authentication Examples - Advanced auth patterns
- Storage Examples - Data management strategies
- Notification Examples - Notification patterns
- Testing Strategies - Testing your application
Troubleshooting
Common issues and solutions:
SDK Not Initializing
- Check environment variables
- Verify domain configuration
- Ensure proper bundle ID
Build Errors
- Verify TypeScript configuration
- Check import paths
- Ensure all dependencies installed
Runtime Errors
- Check browser console
- Verify API endpoints
- Test SDK boot process
For more help, see the Troubleshooting Guide.