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 🙏

© 2024 – Pkg Stats / Ryan Hefner

clerk-sveltekit

v0.4.2

Published

Adapter to use Clerk with SvelteKit

Downloads

1,853

Readme

Clerk SvelteKit

Adapter for using Clerk authentication in SvelteKit.

Demo

The demo site is just this repository, hosted on Cloudflare Pages.

Installation

Install package

# npm
npm i clerk-sveltekit

# pnpm
pnpm i clerk-sveltekit

# yarn
yarn add clerk-sveltekit

# bun
bun i clerk-sveltekit

Set up environment variables

Add these values to your .env (get them from Clerk after creating an application there):

PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_abcdefg123
CLERK_SECRET_KEY=sk_test_abcdefg123

The easiest way to get these values is to click "API Keys" in the Clerk dashboard, and then copy the values for Next.js, and change NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY to PUBLIC_CLERK_PUBLISHABLE_KEY.

Note that for production sites using OAuth providers, you will have to do some more setup with Clerk and DNS.

Configure the server hook

Add this to src/hooks.server.ts (or integrate this code with your existing hooks.server.ts file):

import type { Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
import { handleClerk } from 'clerk-sveltekit/server'
import { CLERK_SECRET_KEY } from '$env/static/private'

export const handle: Handle = sequence(
	handleClerk(CLERK_SECRET_KEY, {
		debug: true,
		protectedPaths: ['/admin'],
		signInUrl: '/sign-in',
	})
)

Configure the client hook

Add this to src/hooks.client.ts:

import type { HandleClientError } from '@sveltejs/kit'
// To use Clerk components:
import { initializeClerkClient } from 'clerk-sveltekit/client'
// Or for headless mode:
// import { initializeClerkClient } from 'clerk-sveltekit/headless'
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public'

initializeClerkClient(PUBLIC_CLERK_PUBLISHABLE_KEY, {
	afterSignInUrl: '/admin/',
	afterSignUpUrl: '/admin/',
	signInUrl: '/sign-in',
	signUpUrl: '/sign-up',
})

export const handleError: HandleClientError = async ({ error, event }) => {
	console.error(error, event)
}

Customize the protected paths, and the various URLs as you like.

[!NOTE] If you use clerk-sveltekit/headless instead of clerk-sveltekit/client, your bundle will be much smaller (by about 1MB), but you will not have access to <SignIn />, <SignUp />, <UserProfile />, <UserButton />, <OrganizationProfile />, <OrganizationSwitcher />, or <CreateOrganization />. Sign-ins will have to happen on your accounts.{TLD} subdomain.

Use the components

Next, put the SignIn component on your sign in page:

<script lang="ts">
	import SignIn from 'clerk-sveltekit/client/SignIn.svelte'
</script>

<div>
	<SignIn redirectUrl="/admin" />
</div>

And put the SignUp component on your sign up page:

<script lang="ts">
	import SignUp from 'clerk-sveltekit/client/SignUp.svelte'
</script>

<div>
	<SignUp redirectUrl="/admin" />
</div>

Then, where you want to show the signed in user's photo and sign out button (probably in a +layout.svelte file in the header):

<script lang="ts">
	import UserButton from 'clerk-sveltekit/client/UserButton.svelte'
	import SignedIn from 'clerk-sveltekit/client/SignedIn.svelte'
	import SignedOut from 'clerk-sveltekit/client/SignedOut.svelte'
</script>

<SignedIn>
	<UserButton afterSignOutUrl="/" />
</SignedIn>
<SignedOut>
	<a href="/sign-in">Sign in</a> <span>|</span> <a href="/sign-up">Sign up</a>
	<!-- You could also use <SignInButton mode="modal" /> and <SignUpButton mode="modal" /> here -->
</SignedOut>

Components

All components can be imported from clerk-sveltekit/client/ComponentName.svelte

  • <ClerkLoading /> — Wrapper that shows its contents when Clerk is still loading.
  • <ClerkLoaded let:clerk /> — Wrapper that shows its contents (and exposes the clerk object) when Clerk is done loading.
  • <SignIn /> — Renders a sign-in form.
  • <SignUp /> — Renders a sign-up form.
  • <SignedIn let:user /> — Wrapper that shows its contents (and exposes the Clerk user object) when the user is signed in.
  • <SignedOut /> — Wrapper that shows its contents when the user is not signed in.
  • <UserButton /> — Button that shows the user’s profile photo with log out link when they are signed in.
  • <UserProfile /> — Renders the current user’s profile.
  • <SignInButton /> — Unstyled sign-in button (can do mode="modal" too).
  • <SignUpButton /> — Unstyled sign-up button (can do mode="modal" too).
  • <SignOutButton /> — Unstyled sign-out button.
  • <OrganizationProfile /> — Renders the organization profile component.
  • <OrganizationSwitcher /> — Renders an organization switcher component.
  • <CreateOrganization /> — Renders UI for creating an organization.

Note that components should be used for displaying UI, but are not sufficient for protecting routes. To protect a route, use the protectedPaths option passed to handleClerk() in your hooks.server.ts file.

Protected Routes

The protectedPaths option will accept an array of either strings, or functions which accept a SvelteKit event object and return a boolean. When passed strings, any route that starts with that string will be protected. i.e. protecting '/admin' will protect /admin but also /admin/foo.

Using Clerk data on the server

Server-side protected routes will automatically get a Clerk user object injected into locals.session which means you can use it in a load() function, a default action, or a form action.

Thanks

Thanks to Cerbos for their https://github.com/cerbos/sveltekit-clerk-cerbos example repo which got this project started, and to Brian Bug for fixing bugs in that implementation.