{"id":50330156,"url":"https://github.com/zitadel/qwik-auth","last_synced_at":"2026-05-29T09:00:38.825Z","repository":{"id":360017959,"uuid":"1248285691","full_name":"zitadel/qwik-auth","owner":"zitadel","description":"A comprehensive Auth.js plugin for Qwik that enables OAuth/OIDC and credential-based authentication.","archived":false,"fork":false,"pushed_at":"2026-05-24T17:09:06.000Z","size":527,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T17:24:15.244Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@zitadel/qwik-auth","language":"TypeScript","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/zitadel.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T12:48:13.000Z","updated_at":"2026-05-24T17:09:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zitadel/qwik-auth","commit_stats":null,"previous_names":["zitadel/qwik-auth"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zitadel/qwik-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fqwik-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fqwik-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fqwik-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fqwik-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zitadel","download_url":"https://codeload.github.com/zitadel/qwik-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zitadel%2Fqwik-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33644313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"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":[],"created_at":"2026-05-29T09:00:32.947Z","updated_at":"2026-05-29T09:00:33.843Z","avatar_url":"https://github.com/zitadel.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Qwik Auth\n\nA [Qwik City](https://qwik.dev/docs/qwikcity/) integration that provides seamless authentication with\nmultiple providers, session management, and Qwik City-native plugin patterns.\n\nThis integration brings the power and flexibility of OAuth to Qwik City\napplications with full TypeScript support, SSR-friendly HTTP handling,\nand Qwik City-native patterns including route plugins and server request events.\n\n### Why?\n\nModern web applications require robust, secure, and flexible authentication\nsystems. Integrating OAuth and session management with Qwik City applications requires careful consideration of\nframework patterns, server-side rendering, and TypeScript integration.\n\nHowever, a direct integration isn't always straightforward. Different types\nof applications or deployment scenarios might warrant different approaches:\n\n- **Plugin Integration:** OAuth and auth flows operate at the HTTP level, while Qwik City\n  uses route plugins (`plugin@*.ts`) and `RequestEventCommon` objects. A proper\n  integration should bridge this gap by providing a plugin-compatible `onRequest`\n  handler that intercepts auth routes transparently.\n- **HTTP Request Handling:** Qwik City's route plugins receive `RequestEventCommon`\n  objects with environment access via `event.env.get()`. This integration wires\n  OAuth into the Qwik request lifecycle without manual response plumbing.\n- **Session and Request Lifecycle:** Proper session handling in Qwik City\n  requires SSR-friendly utilities compatible with Qwik's resumability model\n  and server-side data loading patterns.\n- **Route Protection:** Many applications need fine-grained authorization\n  beyond simple authentication. `getSession()` provides a clean server-side\n  primitive for protecting routes and accessing user data.\n\nThis integration, `@zitadel/qwik-auth`, aims to provide the flexibility to\nhandle such scenarios. It allows you to leverage the full OAuth provider ecosystem\nwhile maintaining Qwik City best practices, ultimately leading to a more\neffective and less burdensome authentication implementation.\n\n## Installation\n\nInstall using NPM by using the following command:\n\n```sh\nnpm install @zitadel/qwik-auth\n```\n\n## Usage\n\nTo use this integration, call `QwikAuth$()` with a plain OAuth config object\nand export the resulting `onRequest`, `useSession`, `useSignIn`, and\n`useSignOut` from a `plugin@auth.ts` route file.\n\nExport the plugin handlers from `plugin@auth.ts`. `QwikAuth$` takes a\nrequest-scoped factory `(event) =\u003e QwikAuthConfig` which the SDK wraps\nin a QRL so server-only imports never enter the client bundle:\n\n```ts\n// src/routes/plugin@auth.ts\nimport { QwikAuth$ } from '@zitadel/qwik-auth';\nimport Zitadel from '@auth/core/providers/zitadel';\n\nexport const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(\n  ({ env }) =\u003e ({\n    providers: [\n      Zitadel({\n        clientId: env.get('ZITADEL_CLIENT_ID'),\n        clientSecret: env.get('ZITADEL_CLIENT_SECRET'),\n        issuer: env.get('ZITADEL_DOMAIN'),\n      }),\n    ],\n    secret: env.get('AUTH_SECRET'),\n    trustHost: true,\n  }),\n);\n```\n\n#### Using the Authentication System\n\nThe integration provides several functions and hooks for handling\nauthentication:\n\n**Plugin Exports (from `plugin@auth.ts`):**\n\n- `onRequest`: Route plugin handler that intercepts auth routes\n- `useSession()`: Server-side session loader (returns `Session | null`)\n- `useSignIn(provider?, options?)`: Initiates sign-in via redirect\n- `useSignOut(options?)`: Initiates sign-out via redirect\n\n**Standalone Server Utility:**\n\n- `getSession(request, config)`: Retrieves the session directly from a request\n\n**Basic Usage in a Route:**\n\n```tsx\n// src/routes/index.tsx\nimport { component$ } from '@builder.io/qwik';\nimport { useSession, useSignIn, useSignOut } from './plugin@auth';\n\nexport default component$(() =\u003e {\n  const session = useSession();\n  const signIn = useSignIn();\n  const signOut = useSignOut();\n\n  return (\n    \u003cdiv\u003e\n      {session.value ? (\n        \u003c\u003e\n          \u003cp\u003eWelcome, {session.value.user?.name}\u003c/p\u003e\n          \u003cbutton onClick$={() =\u003e signOut()}\u003eSign out\u003c/button\u003e\n        \u003c/\u003e\n      ) : (\n        \u003cbutton onClick$={() =\u003e signIn('zitadel')}\u003eSign in\u003c/button\u003e\n      )}\n    \u003c/div\u003e\n  );\n});\n```\n\nPrefer direct session access in a server loader? Use `getSession()`:\n\n```ts\n// src/routes/profile/index.tsx\nimport { routeLoader$ } from '@builder.io/qwik-city';\nimport { getSession } from '@zitadel/qwik-auth';\nimport Zitadel from '@auth/core/providers/zitadel';\n\nexport const useProfileData = routeLoader$(async (event) =\u003e {\n  const session = await getSession(event.request, {\n    providers: [\n      Zitadel({\n        clientId: event.env.get('ZITADEL_CLIENT_ID'),\n        clientSecret: event.env.get('ZITADEL_CLIENT_SECRET'),\n        issuer: event.env.get('ZITADEL_DOMAIN'),\n      }),\n    ],\n    secret: event.env.get('AUTH_SECRET'),\n    trustHost: true,\n  });\n  if (!session) throw event.redirect(302, '/');\n  return session;\n});\n```\n\n##### Example: Advanced Configuration with Multiple Providers\n\nThis example shows how to use the integration with multiple OAuth\nproviders and custom session configuration:\n\n```ts\n// src/routes/plugin@auth.ts\nimport { QwikAuth$ } from '@zitadel/qwik-auth';\nimport Zitadel from '@auth/core/providers/zitadel';\nimport Google from '@auth/core/providers/google';\n\nexport const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(\n  ({ env }) =\u003e ({\n    providers: [\n      Zitadel({\n        clientId: env.get('ZITADEL_CLIENT_ID'),\n        clientSecret: env.get('ZITADEL_CLIENT_SECRET'),\n        issuer: env.get('ZITADEL_DOMAIN'),\n      }),\n      Google({\n        clientId: env.get('GOOGLE_CLIENT_ID'),\n        clientSecret: env.get('GOOGLE_CLIENT_SECRET'),\n      }),\n    ],\n    secret: env.get('AUTH_SECRET'),\n    trustHost: true,\n    session: {\n      strategy: 'jwt',\n      maxAge: 30 * 24 * 60 * 60, // 30 days\n    },\n    callbacks: {\n      async jwt({ token, user }) {\n        if (user) (token as any).roles = (user as any).roles;\n        return token;\n      },\n      async session({ session, token }) {\n        (session.user as any).roles = (token as any).roles as\n          | string[]\n          | undefined;\n        return session;\n      },\n    },\n  }),\n);\n```\n\n## Known Issues\n\n- **Plugin Route Required:** The integration must be wired in a Qwik City\n  plugin route file (`src/routes/plugin@auth.ts`). The `plugin@` prefix is\n  required for Qwik City to recognise it as a request plugin.\n- **Environment Configuration:** The integration relies on `AUTH_SECRET` and,\n  in many hosting scenarios, `AUTH_TRUST_HOST`. Ensure these are correctly set\n  in your environment for production.\n- **Callback URLs:** OAuth providers must be configured with the correct\n  callback URL: `[origin]/api/auth/callback/[provider]`.\n- **Type Augmentation:** If you attach additional properties (e.g., roles) to\n  the user session object, extend your app's types accordingly so consumers of\n  `session.user` remain type-safe.\n- **Redirect Semantics:** OAuth providers expect real browser navigations during\n  sign-in. The `useSignIn` and `useSignOut` helpers handle this for you — avoid\n  manual `fetch()` calls to provider endpoints unless you know you need\n  credential/email flows.\n\n## Useful links\n\n- **[Qwik City](https://qwik.dev/docs/qwikcity/):** The framework this\n  integration targets.\n\n## Contributing\n\nIf you have suggestions for how this integration could be improved, or\nwant to report a bug, open an issue — we'd love all and any contributions.\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzitadel%2Fqwik-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzitadel%2Fqwik-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzitadel%2Fqwik-auth/lists"}