├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE.md ├── stale.yml └── workflows │ └── lint.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── README.md ├── build.js ├── index.d.ts ├── index.js ├── package-lock.json └── package.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [balazsorban44] 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | ## Reasoning 💡 18 | 19 | 25 | 26 | ## Checklist 🧢 27 | 28 | 31 | 32 | - [ ] Documentation 33 | - [ ] Tests 34 | - [ ] Ready to be merged 35 | 36 | 37 | 38 | ## Affected issues 🎟 39 | 40 | 52 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 90 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 14 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | - priority 10 | - bug 11 | # Label to use when marking an issue as stale 12 | staleLabel: stale 13 | # Comment to post when marking an issue as stale. Set to `false` to disable 14 | markComment: > 15 | Hi there! It looks like this issue hasn't had any activity for a while. 16 | It will be closed if no further activity occurs. If you think your issue 17 | is still relevant, feel free to comment on it to keep it open. 18 | Thanks! 19 | # Comment to post when closing a stale issue. Set to `false` to disable 20 | closeComment: > 21 | Hi there! It looks like this issue hasn't had any activity for a while. 22 | To keep things tidy, I am going to close this issue for now. 23 | If you think your issue is still relevant, just leave a comment 24 | and I will reopen it. 25 | Thanks! 26 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Package 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - canary 8 | pull_request: 9 | 10 | jobs: 11 | test: 12 | name: Test 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | node-version: [10, 12, 14] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | 25 | - name: Install dependencies 26 | uses: bahmutov/npm-install@v1 27 | 28 | - run: npm run test:ci 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting me@iaincollins.com. All complaints will be reviewed and 59 | investigated and will result in a response that is deemed necessary and 60 | appropriate to the circumstances. The project team is obligated to maintain 61 | confidentiality with regard to the reporter of an incident. Further details of 62 | specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Not maintained anymore, see: https://github.com/nextauthjs/react-query/issues/7#issuecomment-923099050 2 | 3 |

4 | Next Auth logo    plus sign    React Query logo 9 |

NextAuth.js React-Query Client

10 |

@next-auth/react-query

11 |

React Query wrapper for NextAuth.js session management.

12 |

13 | 14 | Downloads 15 | 16 | 17 | Github Stars 18 | 19 | 20 | Github Stable Release 22 | 23 |

24 |

25 | 26 | ## Overview 27 | 28 | This is an alternative client for `next-auth` based upon [`react-query`](https://react-query.tanstack.com/). It can replace the built-in session management on the client-side by taking advantage of `react-query`'s built-in caching, auto refetching, etc. 29 | 30 | ## Getting Started 31 | 32 | ``` 33 | npm install --save @next-auth/react-query 34 | ``` 35 | 36 | You can then import `useSession` from this package, instead of the core `next-auth` package. More usage details can be found below. 37 | 38 | 39 | ## API Reference 40 | 41 | ### useSession 42 | 43 | ```ts 44 | useSession(params: UseSessionParams) : UseSessionResult 45 | ``` 46 | 47 | React Query wrapper to retrieve `Session`. Replaces `useSession` and `Provider` from `next-auth/client` in codebases where you already use `react-query`. 48 | 49 | #### UseSessionParams 50 | 51 | ```ts 52 | import { useSession } from "@next-auth/react-query" 53 | ... 54 | const [session, loading] = useSession({ 55 | required: true, 56 | redirectTo: "/auth/sign-in?error=InvalidSession", 57 | queryConfig: { 58 | staleTime: 60 * 1000 * 60 * 3, // 3 hours 59 | refetchInterval: 60 * 1000 * 5 // 5 minutes 60 | } 61 | }) 62 | ... 63 | ``` 64 | 65 | | Parameter | Type | Description | Default | 66 | | :-------- | :------- | :-------------------------------- | :-----: | 67 | | `required`| `boolean`| If `true`, will redirect when no session available | `false` | 68 | | `redirectTo`| `string`| When `required: true`, this is where the user will be redirected | `"/api/auth/session"` | 69 | | `queryConfig` | `UseQueryOptions` | See React Query's `useQuery` [Options](https://react-query.tanstack.com/reference/useQuery) | `{}` | 70 | 71 | > TIP: `staleTime` and `refetchInterval` respectively match `clientMaxAge` and `keepAlive` from the [Original API](https://next-auth.js.org/getting-started/client#options). 72 | 73 | #### UseSessionResult 74 | 75 | ```ts 76 | import { useSession } from "@next-auth/react-query" 77 | ... 78 | const [session, loading] = useSession() 79 | ... 80 | ``` 81 | 82 | The [shape](https://github.com/nextauthjs/next-auth/blob/88ec3bad71eb60ed86b3d95d7c4671f9985c96bd/types/client.d.ts#L20-L26) of what `useSession` returns matches the [Original API](https://next-auth.js.org/getting-started/client#usesession). 83 | 84 | ## Acknowledgements 85 | 86 | Based on [this discussion](https://github.com/nextauthjs/next-auth/discussions/1803) between [@kripod](https://github.com/kripod) and [@balazsorban44](https://github.com/balazsorban44) 87 | 88 | ## Contributing 89 | 90 | We're open to all community contributions! If you'd like to contribute in any way, please first read our [Contributing Guide](https://github.com/nextauthjs/next-auth/blob/canary/CONTRIBUTING.md). 91 | 92 | ## License 93 | 94 | ISC 95 | -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | const build = require("esbuild"); 2 | 3 | build 4 | .build({ 5 | entryPoints: ["index.js"], 6 | bundle: true, 7 | minify: true, 8 | loader: { 9 | ".js": "ts" 10 | }, 11 | format: "esm", 12 | external: ["react", "react-dom"], 13 | outfile: "dist/index.mjs" 14 | }) 15 | .catch(() => process.exit(1)); 16 | 17 | build 18 | .build({ 19 | entryPoints: ["index.js"], 20 | bundle: true, 21 | minify: true, 22 | loader: { 23 | ".js": "ts" 24 | }, 25 | format: "cjs", 26 | external: ["react", "react-dom"], 27 | outfile: "dist/index.js" 28 | }) 29 | .catch(() => process.exit(1)); 30 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import { Session } from "next-auth" 2 | import { UseQueryOptions } from "react-query" 3 | 4 | /** 5 | * Fetches session from `/api/auth/session`, 6 | * parses its JSON response, and returns it. 7 | * If there is no session, it returns `null` 8 | */ 9 | export function fetchSession(): Promise 10 | 11 | /** 12 | * React Query wrapper to retrieve `Session`. 13 | * Replaces `useSession` and `Provider` from `next-auth/client` in codebases 14 | * where you already use `react-query`. 15 | * 16 | * [`useSession`](https://next-auth.js.org/getting-started/client#usesession) | 17 | * [`Provider`](https://next-auth.js.org/getting-started/client#provider) | 18 | * [React Query](https://react-query.tanstack.com/guides/ssr#using-nextjs) 19 | */ 20 | export function useSession(params?: { 21 | /** If set to `true`, the returned session is guaranteed to not be `null` */ 22 | required?: R 23 | /** If `required: true`, the user will be redirected to this URL, if they don't have a session */ 24 | redirectTo?: string 25 | /** Configuration for `useQuery` */ 26 | queryConfig?: UseQueryOptions 27 | }): [R extends true ? Session : Session | null, boolean] 28 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { useQuery } from "react-query" 2 | import { useRouter } from "next/router" 3 | 4 | export async function fetchSession() { 5 | const res = await fetch("/api/auth/session") 6 | const session = await res.json() 7 | if (Object.keys(session).length) { 8 | return session 9 | } 10 | return null 11 | } 12 | 13 | export function useSession({ 14 | required, 15 | redirectTo = "/api/auth/signin?error=SessionExpired", 16 | queryConfig = {}, 17 | } = {}) { 18 | const router = useRouter() 19 | const query = useQuery(["session"], fetchSession, { 20 | ...queryConfig, 21 | onSettled(data, error) { 22 | if (queryConfig.onSettled) queryConfig.onSettled(data, error) 23 | if (data || !required) return 24 | router.push(redirectTo) 25 | }, 26 | }) 27 | return [query.data, query.status === "loading"] 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@next-auth/react-query", 3 | "repository": { 4 | "url": "https://github.com/nextauthjs/react-query" 5 | }, 6 | "bugs": { 7 | "url": "https://github.com/nextauthjs/react-query/issues" 8 | }, 9 | "author": "Balázs Orbán ", 10 | "license": "ISC", 11 | "version": "0.0.12", 12 | "description": "React Query wrapper for NextAuth.js session management", 13 | "keywords": [ 14 | "next-auth", 15 | "react-query" 16 | ], 17 | "exports": { 18 | ".": { 19 | "require": "./dist/index.js", 20 | "default": "./dist/index.mjs" 21 | } 22 | }, 23 | "types": "./index.d.ts", 24 | "files": [ 25 | "index.js", 26 | "index.d.ts", 27 | "dist/*" 28 | ], 29 | "scripts": { 30 | "build": "node build.js", 31 | "test:ci": "npm run lint", 32 | "lint": "eslint .", 33 | "lint:fix": "eslint . --fix" 34 | }, 35 | "peerDependencies": { 36 | "next": "^10.0.3", 37 | "next-auth": "^3.15.9", 38 | "react": "^17.0.2", 39 | "react-query": "^3.13.11" 40 | }, 41 | "devDependencies": { 42 | "esbuild": "^0.12.6", 43 | "eslint": "^7.27.0", 44 | "eslint-config-prettier": "^8.3.0", 45 | "next": "^10.0.3", 46 | "next-auth": "^3.15.9", 47 | "prettier": "^2.3.0", 48 | "react": "^17.0.2", 49 | "react-query": "^3.13.11" 50 | }, 51 | "eslintConfig": { 52 | "env": { 53 | "browser": true, 54 | "node": true 55 | }, 56 | "extends": [ 57 | "eslint:recommended", 58 | "prettier" 59 | ], 60 | "parserOptions": { 61 | "ecmaVersion": 2020, 62 | "sourceType": "module" 63 | }, 64 | "ignorePatterns": [ 65 | "node_modules", 66 | "index.d.ts" 67 | ], 68 | "globals": { 69 | "fetch": "readonly" 70 | } 71 | } 72 | } 73 | --------------------------------------------------------------------------------