{"id":27629583,"url":"https://github.com/markjaquith/clerk-sveltekit","last_synced_at":"2025-04-23T15:26:56.766Z","repository":{"id":201115762,"uuid":"702253419","full_name":"markjaquith/clerk-sveltekit","owner":"markjaquith","description":"Clerk adapter for SvelteKit","archived":false,"fork":false,"pushed_at":"2024-08-06T16:35:05.000Z","size":1354,"stargazers_count":139,"open_issues_count":20,"forks_count":20,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-08-09T13:43:40.241Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Svelte","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markjaquith.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-08T23:49:03.000Z","updated_at":"2024-08-07T04:28:27.000Z","dependencies_parsed_at":"2024-01-12T05:41:03.792Z","dependency_job_id":"32d8227d-f023-41c3-987f-a27e486d5aba","html_url":"https://github.com/markjaquith/clerk-sveltekit","commit_stats":null,"previous_names":["markjaquith/clerk-sveltekit"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markjaquith%2Fclerk-sveltekit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markjaquith%2Fclerk-sveltekit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markjaquith%2Fclerk-sveltekit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markjaquith%2Fclerk-sveltekit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markjaquith","download_url":"https://codeload.github.com/markjaquith/clerk-sveltekit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250459150,"owners_count":21434030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-23T15:26:56.047Z","updated_at":"2025-04-23T15:26:56.751Z","avatar_url":"https://github.com/markjaquith.png","language":"Svelte","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clerk SvelteKit\n\nAdapter for using [Clerk](https://clerk.com/) authentication in [SvelteKit](https://kit.svelte.dev/).\n\n[Demo](https://clerk-sveltekit.markjaquith.com/)\n\nThe demo site is just this repository, hosted on Cloudflare Pages.\n\n## Installation\n\n### Install package\n\n```\n# npm\nnpm i clerk-sveltekit\n\n# pnpm\npnpm i clerk-sveltekit\n\n# yarn\nyarn add clerk-sveltekit\n\n# bun\nbun i clerk-sveltekit\n```\n\n### Set up environment variables\n\nAdd these values to your `.env` (get them from Clerk after creating an application there):\n\n```env\nPUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_abcdefg123\nCLERK_SECRET_KEY=sk_test_abcdefg123\n```\n\nThe 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`.\n\nNote that for production sites using OAuth providers, you will have to do some more setup with Clerk and DNS.\n\n### Configure the server hook\n\nAdd this to `src/hooks.server.ts` (or integrate this code with your existing `hooks.server.ts` file):\n\n```typescript\nimport type { Handle } from '@sveltejs/kit'\nimport { sequence } from '@sveltejs/kit/hooks'\nimport { handleClerk } from 'clerk-sveltekit/server'\nimport { CLERK_SECRET_KEY } from '$env/static/private'\n\nexport const handle: Handle = sequence(\n\thandleClerk(CLERK_SECRET_KEY, {\n\t\tdebug: true,\n\t\tprotectedPaths: ['/admin'],\n\t\tsignInUrl: '/sign-in',\n\t})\n)\n```\n\n### Configure the client hook\n\nAdd this to `src/hooks.client.ts`:\n\n```typescript\nimport type { HandleClientError } from '@sveltejs/kit'\n// To use Clerk components:\nimport { initializeClerkClient } from 'clerk-sveltekit/client'\n// Or for headless mode:\n// import { initializeClerkClient } from 'clerk-sveltekit/headless'\nimport { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public'\n\ninitializeClerkClient(PUBLIC_CLERK_PUBLISHABLE_KEY, {\n\tafterSignInUrl: '/admin/',\n\tafterSignUpUrl: '/admin/',\n\tsignInUrl: '/sign-in',\n\tsignUpUrl: '/sign-up',\n})\n\nexport const handleError: HandleClientError = async ({ error, event }) =\u003e {\n\tconsole.error(error, event)\n}\n```\n\nCustomize the protected paths, and the various URLs as you like.\n\n\u003e [!NOTE]\n\u003e 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 `\u003cSignIn /\u003e`, `\u003cSignUp /\u003e`, `\u003cUserProfile /\u003e`, `\u003cUserButton /\u003e`, `\u003cOrganizationProfile /\u003e`, `\u003cOrganizationSwitcher /\u003e`, or `\u003cCreateOrganization /\u003e`. Sign-ins will have to happen on your `accounts.{TLD}` subdomain.\n\n### Use the components\n\nNext, put the `SignIn` component on your sign in page:\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n\timport SignIn from 'clerk-sveltekit/client/SignIn.svelte'\n\u003c/script\u003e\n\n\u003cdiv\u003e\n\t\u003cSignIn redirectUrl=\"/admin\" /\u003e\n\u003c/div\u003e\n```\n\nAnd put the `SignUp` component on your sign up page:\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n\timport SignUp from 'clerk-sveltekit/client/SignUp.svelte'\n\u003c/script\u003e\n\n\u003cdiv\u003e\n\t\u003cSignUp redirectUrl=\"/admin\" /\u003e\n\u003c/div\u003e\n```\n\nThen, where you want to show the signed in user's photo and sign out button (probably in a `+layout.svelte` file in the header):\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n\timport UserButton from 'clerk-sveltekit/client/UserButton.svelte'\n\timport SignedIn from 'clerk-sveltekit/client/SignedIn.svelte'\n\timport SignedOut from 'clerk-sveltekit/client/SignedOut.svelte'\n\u003c/script\u003e\n\n\u003cSignedIn\u003e\n\t\u003cUserButton afterSignOutUrl=\"/\" /\u003e\n\u003c/SignedIn\u003e\n\u003cSignedOut\u003e\n\t\u003ca href=\"/sign-in\"\u003eSign in\u003c/a\u003e \u003cspan\u003e|\u003c/span\u003e \u003ca href=\"/sign-up\"\u003eSign up\u003c/a\u003e\n\t\u003c!-- You could also use \u003cSignInButton mode=\"modal\" /\u003e and \u003cSignUpButton mode=\"modal\" /\u003e here --\u003e\n\u003c/SignedOut\u003e\n```\n\n## Components\n\nAll components can be imported from `clerk-sveltekit/client/ComponentName.svelte`\n\n- `\u003cClerkLoading /\u003e` — Wrapper that shows its contents when Clerk is still loading.\n- `\u003cClerkLoaded let:clerk /\u003e` — Wrapper that shows its contents (and exposes the `clerk` object) when Clerk is done loading.\n- `\u003cSignIn /\u003e` — Renders a sign-in form.\n- `\u003cSignUp /\u003e` — Renders a sign-up form.\n- `\u003cSignedIn let:user /\u003e` — Wrapper that shows its contents (and exposes the Clerk `user` object) when the user is signed in.\n- `\u003cSignedOut /\u003e` — Wrapper that shows its contents when the user is not signed in.\n- `\u003cUserButton /\u003e` — Button that shows the user’s profile photo with log out link when they are signed in.\n- `\u003cUserProfile /\u003e` — Renders the current user’s profile.\n- `\u003cSignInButton /\u003e` — Unstyled sign-in button (can do `mode=\"modal\"` too).\n- `\u003cSignUpButton /\u003e` — Unstyled sign-up button (can do `mode=\"modal\"` too).\n- `\u003cSignOutButton /\u003e` — Unstyled sign-out button.\n- `\u003cOrganizationProfile /\u003e` — Renders the organization profile component.\n- `\u003cOrganizationSwitcher /\u003e` — Renders an organization switcher component.\n- `\u003cCreateOrganization /\u003e` — Renders UI for creating an organization.\n\nNote 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.\n\n## Protected Routes\n\nThe `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`.\n\n## Using Clerk data on the server\n\nServer-side protected routes will automatically get a [Clerk user object](https://clerk.com/docs/references/javascript/user/user) injected into `locals.session` which means you can use it [in a `load()` function](https://kit.svelte.dev/docs/form-actions#loading-data), a [default action](https://kit.svelte.dev/docs/form-actions#default-actions), or a [form action](https://kit.svelte.dev/docs/form-actions).\n\n## Thanks\n\nThanks to Cerbos for their [https://github.com/cerbos/sveltekit-clerk-cerbos](sveltekit-clerk-cerbos) example repo which got this project started, and to [Brian Bug](https://thebrianbug.com/) for fixing bugs in that implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkjaquith%2Fclerk-sveltekit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkjaquith%2Fclerk-sveltekit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkjaquith%2Fclerk-sveltekit/lists"}