Overview
Add your Invent AI assistant to any SvelteKit application. Perfect for Svelte applications with server-side rendering and static generation.
Installation
Create Assistant Component
<!-- src/lib/components/InventAssistant.svelte -->
< script lang = "ts" >
export let assistantId : string ;
export let themeAppearance : 'auto' | 'light' | 'dark' = 'auto' ;
export let themeButtonBackgroundColor : string | undefined = undefined ;
export let themeButtonColor : string | undefined = undefined ;
export let userId : string | undefined = undefined ;
export let userName : string | undefined = undefined ;
export let userHash : string | undefined = undefined ;
export let userAvatar : string | undefined = undefined ;
</ script >
< invent-assistant
assistant-id = { assistantId }
theme-appearance = { themeAppearance }
theme-button-background-color = { themeButtonBackgroundColor }
theme-button-color = { themeButtonColor }
user-id = { userId }
user-name = { userName }
user-hash = { userHash }
user-avatar = { userAvatar }
/>
< script
type = "text/javascript"
src = "https://www.useinvent.com/button.js"
async
defer
></ script >
</Step>
<Step title="Add to Root Layout">
```svelte
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import InventAssistant from '$lib/components/InventAssistant.svelte';
import { PUBLIC_INVENT_ASSISTANT_ID } from '$env/static/public';
</script>
<slot />
<InventAssistant assistantId={PUBLIC_INVENT_ASSISTANT_ID} />
Configure Environment
Add to .env
: PUBLIC_INVENT_ASSISTANT_ID = ast_YOUR_ASSISTANT_ID
INVENT_SECRET_KEY = your_secret_key_here
User Authentication
Security Requirement: When using any user-*
attributes (user-id
, user-name
, user-avatar
), you must also provide user-hash
. Both user-id
and user-hash
must be provided together, or neither should be provided. The user-hash
must be generated on your backend using HMAC-SHA256 with your assistant’s secret key. Never expose the secret key to the client.
Server-Side Hash Generation
Use SvelteKit server endpoints:
// src/routes/api/user-hash/+server.ts
import { json } from '@sveltejs/kit' ;
import { createHmac } from 'crypto' ;
import { INVENT_SECRET_KEY } from '$env/static/private' ;
import type { RequestHandler } from './$types' ;
export const GET : RequestHandler = async ({ locals }) => {
// Get user from your auth system (e.g., lucia, session)
const user = locals . user ;
if ( ! user ) {
return json ({ error: 'Unauthorized' }, { status: 401 });
}
const userId = user . id ;
const userHash = createHmac ( 'sha256' , INVENT_SECRET_KEY )
. update ( userId )
. digest ( 'hex' );
return json ({
userId ,
userName: user . name ,
userAvatar: user . avatar ,
userHash ,
});
};
Using Server Load Functions
// src/routes/+layout.server.ts
import { createHmac } from 'crypto' ;
import { INVENT_SECRET_KEY } from '$env/static/private' ;
import type { LayoutServerLoad } from './$types' ;
export const load : LayoutServerLoad = async ({ locals }) => {
const user = locals . user ;
if ( ! user ) {
return { userData: null };
}
const userId = user . id ;
const userHash = createHmac ( 'sha256' , INVENT_SECRET_KEY )
. update ( userId )
. digest ( 'hex' );
return {
userData: {
userId ,
userName: user . name ,
userAvatar: user . avatar ,
userHash ,
},
};
};
Then use in your layout:
<!-- src/routes/+layout.svelte -->
< script lang = "ts" >
import InventAssistant from '$lib/components/InventAssistant.svelte' ;
import { PUBLIC_INVENT_ASSISTANT_ID } from '$env/static/public' ;
import type { LayoutData } from './$types' ;
export let data : LayoutData ;
</ script >
< slot />
< InventAssistant
assistantId = { PUBLIC_INVENT_ASSISTANT_ID }
userId = { data . userData ?. userId }
userName = { data . userData ?. userName }
userHash = { data . userData ?. userHash }
userAvatar = { data . userData ?. userAvatar }
/>
Integration with Lucia Auth
// src/routes/+layout.server.ts
import { createHmac } from 'crypto' ;
import { INVENT_SECRET_KEY } from '$env/static/private' ;
import type { LayoutServerLoad } from './$types' ;
export const load : LayoutServerLoad = async ({ locals }) => {
const session = await locals . auth . validate ();
if ( ! session ?. user ) {
return { userData: null };
}
const userId = session . user . userId ;
const userHash = createHmac ( 'sha256' , INVENT_SECRET_KEY )
. update ( userId )
. digest ( 'hex' );
return {
userData: {
userId ,
userName: session . user . name ,
userAvatar: session . user . avatar ,
userHash ,
},
};
};
TypeScript Support
Add type declarations:
// src/app.d.ts
declare global {
namespace App {
interface Locals {
user ?: {
id : string ;
name : string ;
avatar ?: string ;
};
}
}
namespace svelteHTML {
interface HTMLAttributes < T > {
'assistant-id' ?: string ;
'theme-appearance' ?: 'auto' | 'light' | 'dark' ;
'theme-button-background-color' ?: string ;
'theme-button-color' ?: string ;
'user-id' ?: string ;
'user-name' ?: string ;
'user-hash' ?: string ;
'user-avatar' ?: string ;
}
}
interface Window {
inventContext ?: Record < string , any >;
}
}
export {};
Using Stores
Create a store for user authentication:
// src/lib/stores/inventAuth.ts
import { writable } from 'svelte/store' ;
import { browser } from '$app/environment' ;
interface UserData {
userId : string ;
userName : string ;
userHash : string ;
userAvatar ?: string ;
}
function createInventAuthStore () {
const { subscribe , set } = writable < UserData | null >( null );
return {
subscribe ,
fetchUserAuth : async () => {
if ( ! browser ) return ;
try {
const response = await fetch ( '/api/user-hash' );
const data = await response . json ();
set ( data );
} catch ( error ) {
set ( null );
}
},
clear : () => set ( null ),
};
}
export const inventAuth = createInventAuthStore ();
Usage:
<!-- src/routes/+layout.svelte -->
< script lang = "ts" >
import { onMount } from 'svelte' ;
import { inventAuth } from '$lib/stores/inventAuth' ;
import InventAssistant from '$lib/components/InventAssistant.svelte' ;
import { PUBLIC_INVENT_ASSISTANT_ID } from '$env/static/public' ;
onMount (() => {
inventAuth . fetchUserAuth ();
});
</ script >
< slot />
< InventAssistant
assistantId = { PUBLIC_INVENT_ASSISTANT_ID }
userId = { $ inventAuth ?. userId }
userName = { $ inventAuth ?. userName }
userHash = { $ inventAuth ?. userHash }
userAvatar = { $ inventAuth ?. userAvatar }
/>
Tips for SvelteKit
Server Load Functions Use server load for secure hash generation
Type Safety Full TypeScript support with proper types
SSR Compatible Works with SSR and SPA modes
Reactive Leverage Svelte’s reactivity system
Troubleshooting
Solutions:
Check browser guard: if (browser)
Ensure script loads in onMount
Verify URL is correct
Check browser console for errors
Solutions:
Use browser check before accessing window
Load script client-side only
Ensure user data is fetched client-side if needed
Environment variables not working
Solutions:
Restart dev server after adding env variables
Use PUBLIC_
prefix for public variables
Keep secret key without prefix (private)
Check import from correct $env module
Best Practices
Use server load functions or endpoints for hash generation
Keep secret key in .env
(never commit)
Use PUBLIC_
prefix only for non-sensitive variables
Always check browser
before accessing window
Leverage SvelteKit’s built-in security features