Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/wobsoriano/svelte-clerk

Community Clerk Svelte SDK.
https://github.com/wobsoriano/svelte-clerk

authentication authorization clerk svelte

Last synced: 4 days ago
JSON representation

Community Clerk Svelte SDK.

Awesome Lists containing this project

README

        

# Svelte Clerk

Community package that integrates [Clerk](https://clerk.com/) with [SvelteKit](https://kit.svelte.dev/).

> [!IMPORTANT]
> This package requires Svelte 5 and uses [`runes`](https://svelte-5-preview.vercel.app/docs/runes) and [`snippets`](https://svelte-5-preview.vercel.app/docs/snippets) under the hood. If you're using Svelte 4, please refer to [clerk-sveltekit](https://github.com/markjaquith/clerk-sveltekit).

## Installation

```bash
npm install svelte-clerk
```

## Set your Clerk API keys

```bash
PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxxxxx
CLERK_SECRET_KEY=sk_test_xxxxxxx
```

## Configure server handler

This handler will authenticate a token passed from the frontend and attaches the [`Auth`](https://clerk.com/docs/references/nextjs/auth-object#auth-object) object to `event.locals.auth`.

```ts
// hooks.server.ts
import { withClerkHandler } from 'svelte-clerk/server';

export const handle = withClerkHandler();
```

## Update `app.d.ts`

Inside your `src/` directory, update the `app.d.ts` file to ensure that the locals added by the Clerk handler are properly typed.

```ts
///

declare global {
namespace App {...}
}
```

## Add `` to your root layout

All Clerk runes and components must be children of the `` component, which provides active session and user context.

```ts
// src/+layout.server.ts
import { buildClerkProps } from 'svelte-clerk/server';

// To enable Clerk SSR support, add initial state props to the load function
export const load = ({ locals }) => {
return {
...buildClerkProps(locals.auth)
};
};
```

```svelte

import type { Snippet } from '@svelte';
import { ClerkProvider } from 'svelte-clerk';

const { children }: { children: Snippet } = $props();

{@render children()}

```

## Components

To see all available props for each component, visit the [Clerk UI Components](https://clerk.com/docs/components/overview) docs.

- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``
- ``

## Runes

- `auth` - [Auth](https://clerk.com/docs/references/nextjs/auth-object#auth-object) object.
- `user` - Authenticated [user](https://clerk.com/docs/references/javascript/user/user).
- `organization` - Active [Organization](https://clerk.com/docs/references/javascript/organization/organization) of the authenticated user.
- `session` - [Session](https://clerk.com/docs/references/javascript/session) of the authenticated user.
- `clerk` - [`Clerk`](https://clerk.com/docs/references/javascript/clerk/clerk) object.

Example:

The following example demonstrates how to use the `auth` rune to access the current auth state, like whether the user is signed in or not. It also demonstrates a basic example of how you could use the [`getToken()`](https://clerk.com/docs/references/javascript/session#get-token) method to retrieve a session token for fetching data from an external resource.

```svelte

import { useClerkContext } from 'svelte-clerk';

// Do not destructure context or you'll lose reactivity!
const ctx = useClerkContext();
const userId = $derived(ctx.auth.userId);

const fetchDataFromExternalResource = async () => {
const token = await ctx.session.getToken();
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${token}`
}
});
return response.json();
};

{#if userId === undefined}

Loading...


{:else if userId === null}

Sign in to view this page


{:else}
...

{/if}
```

## Protecting routes

### Client side

Clerk offers Control Components that allow you to protect your pages. These components are used to control the visibility of your pages based on the user's authentication state.

```svelte

import { SignedIn, SignedOut, UserButton, SignOutButton } from 'svelte-clerk';


Index Route



You are signed in!



View your profile here 👇









You are signed out



Go to Sign in


Go to Sign up



```

### Server side

To protect your routes, you can use the load function to check for the `userId` singleton. If it doesn't exist, redirect your user back to the sign-in page.

```ts
import { redirect } from '@sveltejs/kit';
import { clerkClient } from 'svelte-clerk/server';

export const load = ({ locals }) => {
const { userId } = locals.auth;

if (!userId) {
return redirect(307, '/sign-in');
}

const user = await clerkClient.users.getUser(userId);

return {
user: JSON.parse(JSON.stringify(user))
};
};
```

> [!NOTE]
> If you're planning to add authorization logic within a `+layout.server.ts` file, I recommend reading [this blog post](https://www.captaincodeman.com/securing-your-sveltekit-app) first.

## License

MIT