{"id":19898402,"url":"https://github.com/alanacdz/sveltekit-fireauth","last_synced_at":"2026-02-15T01:02:21.056Z","repository":{"id":195998417,"uuid":"683205943","full_name":"AlanAcDz/sveltekit-fireauth","owner":"AlanAcDz","description":"A SvelteKit library for seamless server-side authentication using Firebase Authentication.","archived":false,"fork":false,"pushed_at":"2023-09-20T21:01:07.000Z","size":109,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-20T06:04:52.615Z","etag":null,"topics":["authentication","firebase","firebase-auth","svelte","sveltekit"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlanAcDz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null},"funding":{"github":["AlanAcDz"]}},"created_at":"2023-08-25T21:20:06.000Z","updated_at":"2024-09-27T18:21:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"30ed8c12-0fe4-49e8-80b2-ab4a056fc4e3","html_url":"https://github.com/AlanAcDz/sveltekit-fireauth","commit_stats":null,"previous_names":["alanacdz/sveltekit-fireauth"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AlanAcDz/sveltekit-fireauth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlanAcDz%2Fsveltekit-fireauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlanAcDz%2Fsveltekit-fireauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlanAcDz%2Fsveltekit-fireauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlanAcDz%2Fsveltekit-fireauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlanAcDz","download_url":"https://codeload.github.com/AlanAcDz/sveltekit-fireauth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlanAcDz%2Fsveltekit-fireauth/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266911108,"owners_count":24005045,"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","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["authentication","firebase","firebase-auth","svelte","sveltekit"],"created_at":"2024-11-12T19:04:16.494Z","updated_at":"2026-02-15T01:02:21.005Z","avatar_url":"https://github.com/AlanAcDz.png","language":"TypeScript","funding_links":["https://github.com/sponsors/AlanAcDz"],"categories":[],"sub_categories":[],"readme":"[![Release](https://github.com/AlanAcDz/sveltekit-fireauth/actions/workflows/release.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/AlanAcDz/sveltekit-fireauth/actions/workflows/release.yaml)\n[![npm](https://img.shields.io/npm/v/sveltekit-fireauth/latest)](https://www.npmjs.com/package/sveltekit-fireauth)\n\n# sveltekit-fireauth\n\nA SvelteKit library for seamless server-side authentication using Firebase Authentication.\n\nPartially inspired by [next-firebase-auth](https://github.com/gladly-team/next-firebase-auth), check out its discussion of [when (not) to use this package](https://github.com/gladly-team/next-firebase-auth#when-not-to-use-this-package).\n\nThis is a new library so bugs are expected, please open a new issue if you encounter any or (better yet) open a new PR. Please be patient as this is a one man team here :)\n\n## To do\n\n- [ ] Make it work with Firebase emulator\n- [ ] Fully automate releases\n\n## Quick start\n\nThis guide will assume your app uses typescript\n\n1. Install this package with peer dependencies\n\n```bash\n npm i sveltekit-fireauth firebase firebase-admin\n```\n\n2. Set up the required types in `app.d.ts`\n\n```typescript\nimport type { FirebaseAuth } from 'sveltekit-fireauth/server'\n\ndeclare global {\n  namespace App {\n    interface Locals {\n      auth: FirebaseAuth\n    }\n  }\n}\n\nexport {}\n```\n\n3. Set up a handle hook inside `hooks.server.ts`\n\n```typescript\nimport type { Handle } from '@sveltejs/kit'\nimport { createAuthHandle } from 'sveltekit-fireauth/server'\nimport { FIREBASE_SERVICE_ACCOUNT_KEY } from '$env/static/private'\n\nexport const handle: Handle = createAuthHandle({\n  // Your web app's Firebase configuration\n  firebaseConfig: {\n    apiKey: '',\n    authDomain: '',\n    projectId: '',\n    storageBucket: '',\n    messagingSenderId: '',\n    appId: '',\n  },\n  // Optional. Just set the FIREBASE_SERVICE_ACCOUNT_KEY environment variable and the library will pick it up\n  serviceAccountKey: FIREBASE_SERVICE_ACCOUNT_KEY,\n  // Optional. Refresh token cookie expire time, default 30 days\n  refreshExpireTime: 60 * 60 * 24 * 30,\n})\n```\n\nYou may want to use the [sequence](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks-sequence) helper function to set up multiple handle hooks, especially if you are going to use this library's other handle hooks.\n\n4. Set up some form actions to log in, sign up and log out a user.\n\n```typescript\nimport { loginWithCredentials, signupWithCredentials, signOut } from 'sveltekit-fireauth/server'\n\nexport const actions = {\n  login: async (event) =\u003e {\n    // Get the email and password from the form\n    try {\n      await loginWithCredentials({ event, email, password })\n    } catch (e) {\n      throw error(401, { message: 'Unauthorized' })\n    }\n    throw redirect(303, '/protected')\n  },\n  signup: async (event) =\u003e {\n    // Get the email and password from the form\n    try {\n      await signupWithCredentials({ event, email, password })\n    } catch (e) {\n      throw error(401, { message: 'Account cannot be created' })\n    }\n    throw redirect(303, '/protected')\n  },\n  logout: async ({ cookies }) =\u003e {\n    return signOut({ cookies, redirectRoute: '/login' })\n  },\n}\n```\n\nIf you prefer so, this could be done using request handlers as well.\n\n5. Pass the user's session to the client-side\n\n```typescript\n// +layout.server.ts\nimport { verifySession } from 'sveltekit-fireauth/server'\n\nexport const load = (event) =\u003e ({\n  session: verifySession(event),\n})\n```\n\n```svelte\n\u003c!-- +layout.svelte --\u003e\n\u003cscript lang=\"ts\"\u003e\n  export let data\n\n  $: ({ session } = data)\n\u003c/script\u003e\n\n\u003cp\u003eLogged in as user: {session.uid}\u003c/p\u003e\n```\n\n## Recipes\n\n### Protecting Pages\n\nYou can protect a page using the `onlyAuthenticatedLoad` function inside any page's `+page.server.ts` file. For example:\n\n```typescript\n// /protected/+page.server.ts\nimport { onlyAuthenticatedLoad } from 'sveltekit-fireauth/server'\n\nexport const load = onlyAuthenticatedLoad({\n  redirectRoute: '/login',\n  load: () =\u003e {\n    // regular load function here\n  },\n})\n```\n\nPassing a load function is optional, in case a particular page does not load anything from the server.\n\n```typescript\n// /protected/+page.server.ts\nimport { onlyAuthenticatedLoad } from 'sveltekit-fireauth/server'\n\nexport const load = onlyAuthenticatedLoad({\n  redirectRoute: '/login',\n})\n```\n\nThis approach gives you the flexibility to handle authentication on a per page basis and without introducing waterfalls. This also seems to be the recommended approach to handle authentication in SvelteKit, at least as a TLDR from [this discussion](https://github.com/sveltejs/kit/issues/6315).\n\nHowever, I'm aware this approach also introduces some overhead, having to call `onlyAuthenticatedLoad` on every page you want to protect. So this library also includes a `createProtectedRoutesHandle` for you to use in your `hooks.server.ts`.\n\n```typescript\nimport { createAuthHandle } from 'sveltekit-fireauth/server'\n\nconst protectedRoutesHandle: Handle = createProtectedRoutesHandle({\n  baseRoute: '/protected', // the group of routes you want to protect\n  redirectRoute: '/login',\n})\n\nexport const handle = sequence(/* ... */)\n```\n\nThere also exists `onlyPublicLoad` and `createPublicRoutesHandle` functions for you to keep your authenticated users out of your login page (or any page you want).\n\n### Syncing authentication state with the client\n\nIf you're using the Firebase SDK on the client and have security rules for Firestore or Storage you will need to sync the server-side session with the client.\n\n1. In a `+layout.server.ts` file load the session and auth config object. This object is the Firebase SDK config object. If you're creating your own Firebase SDK client you don't need to load auth config here\n\n```typescript\n// +layout.server.ts\nimport { verifySession } from 'sveltekit-fireauth/server'\n\nexport const load = (event) =\u003e ({\n  authConfig: event.locals.auth.config,\n  session: verifySession(event),\n})\n```\n\n2. In the `+layout.ts` file get the session that was loaded from the server and create the Firebase Auth client using the auth config. If you're creating your own Firebase SDK client you don't need to create the Firebase Auth client here.\n\n```typescript\n// +layout.ts\nimport { createFirebaseAuth } from 'sveltekit-fireauth/client'\n\nexport const load = ({ data }) =\u003e ({\n  auth: createFirebaseAuth(data.authConfig),\n  session: data.session,\n})\n```\n\n3. In the `+layout.svelte` file use the `syncAuthState` function inside an onMount callback.\n\n```svelte\n\u003c!-- +layout.svelte --\u003e\n\u003cscript lang=\"ts\"\u003e\n  import { onMount } from 'svelte'\n  import { syncAuthState } from 'sveltekit-fireauth/client'\n\n  export let data\n\n  $: ({ session, auth } = data)\n\n  onMount(() =\u003e {\n    const unsubscribe = syncAuthState(auth, session)\n    return () =\u003e {\n      unsubscribe()\n    }\n  })\n\u003c/script\u003e\n```\n\n### OAuth\n\nIt's possible to use OAuth with this library, however it requires a bit more setup, specially if you're using form actions. You may want to use an API route instead.\n\nAssuming you're using an API route, here's what you need:\n\n1. Setup the API route. This is going to receive an ID token and use the `loginWithIdToken` helper to log in the user.\n\n```typescript\n// /login/oauth/+server.ts\nimport { error, json } from '@sveltejs/kit'\nimport { loginWithIdToken } from 'sveltekit-fireauth/server'\n\nexport const POST = async (event) =\u003e {\n  const { token } = await event.request.json()\n  if (!token) {\n    throw error(400, { message: 'Missing token' })\n  }\n  try {\n    await loginWithIdToken({ event, token })\n  } catch (e) {\n    throw error(401, { message: 'Unauthorized' })\n  }\n  return json({ success: true })\n}\n```\n\n2. Next setup your login button with an on click handler. We'll use Google sign in for this example. Notice how in this case we sign in on the client first to get the ID token and then on the server with that token.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { invalidateAll } from '$app/navigation'\n  import { GoogleAuthProvider, signInWithPopup, signOut } from 'firebase/auth'\n\n  export let data\n\n  const googleLogin = async () =\u003e {\n    const provider = new GoogleAuthProvider()\n    const { user } = await signInWithPopup(data.auth, provider)\n    const token = user.getIdToken()\n    const response = await fetch('/login/oauth', {\n      method: 'POST',\n      body: JSON.stringify({ token }),\n    })\n    if (!response.ok) {\n      // handle login failure\n      await signOut(data.auth)\n    }\n    await invalidateAll()\n  }\n\u003c/script\u003e\n\n\u003cbutton on:click={googleLogin}\u003eSign in with Google\u003c/button\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falanacdz%2Fsveltekit-fireauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falanacdz%2Fsveltekit-fireauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falanacdz%2Fsveltekit-fireauth/lists"}