Giter Club home page Giter Club logo

vue-query-nuxt's Introduction

⚗️ Vue Query Nuxt

CI npm version npm downloads License: MIT

🚀 Welcome to Vue Query Nuxt!

This Nuxt Module automatically installs and configure Vue Query for your Nuxt application. It has 0 config out-of-the box and extremely lightweight.

Features

  • 0 config out-of-the box
  • All configurations options available
  • Auto Imports for Vue Query composables

Refer to the Vue Query documentation for more information about Vue Query.

📦 How to use

1. Use npm, pnpm or yarn to install the dependencies.

# npm
npm i @hebilicious/vue-query-nuxt @tanstack/vue-query  
# pnpm
pnpm i @hebilicious/vue-query-nuxt @tanstack/vue-query  
# yarn
yarn add @hebilicious/vue-query-nuxt @tanstack/vue-query  

2. Add the modules to your Nuxt modules

In nuxt.config.ts :

export default defineNuxtConfig({
  modules: ["@hebilicious/vue-query-nuxt"]
})

3. Use right away

In a vue component :

<script setup lang="ts">
// Access QueryClient instance
const queryClient = useQueryClient()

// Query
const { isLoading, isError, data, error } = useQuery({
  queryKey: ['todos'],
  queryFn: () => $fetch("/api/todos"), // Use $fetch with your api routes to get typesafety 
})

// Mutation
const { mutate } = useMutation({
  mutationFn: (newTodo) => $fetch("/api/todos", { method: "POST", body: newTodo })
  onSuccess: () => {
    // Invalidate and refetch
    queryClient.invalidateQueries({ queryKey: ['todos'] })
  },
})

function onButtonClick() {
   mutate({
    id: Date.now(),
    title: 'Do Laundry',
  })
}
</script>

<template>
  <span v-if="isLoading">Loading...</span>
  <span v-else-if="isError">Error: {{ error.message }}</span>
  <!-- We can assume by this point that `isSuccess === true` -->
  <ul v-else>
    <li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
  </ul>
  <button @click="onButtonClick">Add Todo</button>
</template>

4. Advanced configuration

You can specify the options under the vueQuery key in your nuxt.config.ts file. Everything is typed.

In nuxt.config.ts :

export default defineNuxtConfig({
  modules: ["@hebilicious/vue-query-nuxt"],
  vueQuery: {
    // useState key used by nuxt for the vue query state.
    stateKey: "vue-query-nuxt", // default
    // If you only want to import some functions, specify them here.
    // You can pass false or an empty array to disable this feature.
    // default: ["useQuery", "useQueries", "useInfiniteQuery", "useMutation", "useIsFetching", "useIsMutating", "useQueryClient"]
    autoImports: ["useQuery"],
    // Pass the vue query client options here ...
    queryClientOptions: {
      defaultOptions: { queries: { staleTime: 5000 } } // default
    },
    // Pass the vue query plugin options here ....
    vueQueryPluginOptions: {}
  }
})

If you need to modify the plugin that installs vue query, you can create a vue-query.config.ts file at the root of your project.

In vue-query.config.ts :

import { library } from "@example/libray"

export default defineVueQueryPluginHook(({ queryClient, nuxt }) => {
  console.log(queryClient, nuxt) // You can access the queryClient here
  return {
    pluginReturn: { provide: { library, test: console } }, // nuxt plugin return value
    vueQueryPluginOptions: { queryClient } // You can pass dynamic options
  }
})

This hook will be run within the nuxt plugin installed by the module, so you can use it to provide something or replace the vue query options. This can be useful if you need to run custom logic when the queryClient is being installed.

📦 Contributing

Contributions, issues and feature requests are welcome!

  1. Fork this repo

  2. Install node and pnpm Use corepack enable && corepack prepare pnpm@latest --activate to install pnpm easily

  3. Use pnpm i at the mono-repo root.

  4. Make modifications and follow conventional commits.

  5. Open a PR 🚀🚀🚀

vue-query-nuxt's People

Contributors

hebilicious avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vue-query-nuxt's Issues

vue-query usage with useFetch

Environment

node:18.1.0
"devDependencies": {
"@css-render/vue3-ssr": "^0.15.12",
"@nuxt/devtools": "1.0.0",
"@nuxtjs/color-mode": "^3.3.0",
"@unocss/nuxt": "^0.56.5",
"naive-ui": "^2.35.0",
"nuxt": "^3.7.4",
"nuxt-icon": "^0.5.0",
"unplugin-vue-components": "^0.25.2",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
"dependencies": {
"@hebilicious/vue-query-nuxt": "^0.2.1",
"@nuxt/image": "^1.0.0-rc.3",
"@tanstack/vue-query": "^5.0.0"
}

Reproduction

<template>
  <div>
    <span v-if="isLoading">Loading...</span>
    <span v-else-if="isError">Error: {{ error!.message }}</span>
    <ul v-else>
      <li>
        {{ data }}
      </li>
    </ul>
  </div>
</template>

<script lang="ts" setup>
const {
  isLoading = true,
  isError,
  data,
  error,
} = useQuery<any>({
  queryKey: ["test"],
  queryFn: async () => {
    const { data } = await useFetch("https://fakestoreapi.com/carts", {
      method: "GET",
    });
    return data;
  },
});
</script>

<style></style>

Describe the bug

Warnings will appear when using `useFetch:

(chunk-RAKT47ZN.js:1449 [Vue warn]: Hydration node mismatch:
- Client vnode: span 
- Server rendered DOM: <ul data-v-inspector=​"src/​pages/​network.vue:​5:​5">​…​</ul>​  
  at <Network onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouteProvider key="/network" vnode= {__v_isVNode: true, __v_skip: true, type: {…}, props: {…}, key: null, …} route= {fullPath: '/network', hash: '', query: {…}, name: 'network', path: '/network', …}  ... > 
  at <RouterView name=undefined route=undefined > 
  at <NuxtPage> 
  at <MessageProvider> 
  at <ConfigProvider locale= {name: 'zh-CN', global: {…}, Popconfirm: {…}, Cascader: {…}, Time: {…}, …} date-locale= {name: 'zh-CN', locale: {…}} theme-overrides= {common: {…}}  ... > 
  at <Default ref=Ref< undefined > > 
  at <LayoutLoader key="default" layoutProps= {ref: RefImpl} name="default" > 
  at <NuxtLayoutProvider layoutProps= {ref: RefImpl} key="default" name="default"  ... > 
  at <NuxtLayout> 
  at <App key=3 > 
  at <NuxtRoot>)`

No warnings will appear when using $fetch

Additional context

No response

Logs

No response

Unable to use in composable

Environment

❯ node -v
v20.11.1

"@hebilicious/vue-query-nuxt": "^0.3.0",

Reproduction

composables/useQueryWrapper.ts

import { experimental_createPersister } from '@tanstack/query-persist-client-core'
import type { GetUserQuery } from '~/API'

export default async function useQueryWrapper() {
  const queryClient = useQueryClient()

  const { isLoading, isError, data, error } = useQuery({
    queryKey: ['getUser'],
    queryFn: async () => {
      const { data } = await useLeanGraphql({
        variables: { id: '9e98ae52-1f4b-47ad-9661-afb2c7efc653' },
        graphqlAction: getUser,
        fields: {
          name: 'getUser',
          fields: getUserSharedFields(true) as Field<GetUserQuery>['fields'],
        },
      })
      return data
      // console.log({ data })
    },
    persister: process.client ? experimental_createPersister({ storage: window.localStorage }) : undefined,
  })

  console.log({
    queryClient,
    isLoading,
    isError,
    data,
    error,
  })

  return { queryClient, isLoading, isError, data, error }
}

plugins/03.auth-redirect.ts

import { Amplify } from 'aws-amplify'
import config from '~/amplifyconfiguration.json'

const unprotectedRoutes = [
  'index',
  'signin',
  'signup',
  'recovery',
  'cause-areas',
  'demo-amplify',
  'cookie-policy',
  'privacy-policy',
  'recovery-confirm',
  'terms-of-service',
]

export default defineNuxtPlugin({
  name: 'AmplifyAuthRedirect',
  enforce: 'pre',
  setup() {
    addRouteMiddleware(
      'AmplifyAuthMiddleware',
      defineNuxtRouteMiddleware(async (to) => {
        try {
          // if we're running on the client, initialize Amplify
          if (process.client)
            Amplify.configure(config, { ssr: useRuntimeConfig().public.ssrEnabled })

          // does the user have a valid session?
          // !! deleted users still possess valid tokens for 1 hour (Cognito "feature")
          const { userId } = await useAuth().getCurrentUser()

          // if the user has a valid session, fetch their user data
          if (userId) {

            // !! testing simple getUser with Id query via vue-query
            try {
              const TESTINGTHIS = await useQueryWrapper()          // 👈 Doesn't work!
              useLogger().info('useQueryWrapper', TESTINGTHIS)
            }
            catch (e) {
              useLogger().error('useQueryWrapper error', e)
            }

            // existing pinia-based implementation
            if (useAuthStore().isLoggedIn === false) {
              // if not, fetch it from the API
              await useAuthStore().fetchCurrentUser(userId)
            }

            if (to.name === 'signin')
              return navigateTo('/feed')
          }
        }
        catch (e) {
          if (e instanceof Error && 'code' in e) {
            if (e.code === 'NotAuthorizedException') {
              useLogger().error('NotAuthorizedException')
              return
            }
          }

          if (!unprotectedRoutes.includes(to.name))
            return navigateTo('/signin')
        }
      }),
      { global: true },
    )
  },
})

Describe the bug

Hi! Thanks for all your great work on this plugin :)

I'm struggling with just one specific implementation.

  • I'm able to call useQueryWrapper in the setup block of one of my pages.
  • I'm able to call useQueryWrapper in my Pinia store (I <3 Pinia, but I'm tryna replace it with vue-query, so I'm really only calling useQueryWrapper from inside pinia as a test...)

In my my authStore.ts (pinia), I can successfully do this:

  useQueryWrapper().then((data) => {
    console.log("Hai antfu, posva, and herbilicious! ", data)
  })
  • I'm unable to call useQueryWrapper from inside the global middleware I create in the plugin I've shared above.

If I could, I'd implement that whole plugin differently, but this is the specific way that the AWS Amplify documentation insists that we implement a routeGuard with SSR + Nuxt3 + Amplify.

I did do lots of digging and searching, and I found this: TanStack/query#5533

I don't understand how we're not getting any context from inside a plugin...I'm just confused (and probably a bit of a newb).

Based on that discussion, I even tried to do useNuxtApp().runWithContext(async () => await useQueryWrapper()) from inside the 03.auth-redirect.ts plugin.

I'm totally stuck. Would you happen to have any suggestion or idea as to how I can get this working. I'm sure that I'm missing something stupid/ovious, but it's 4AM here and I'm already starting to lose it 😂

Thank you for any help or direction you may be able to provide! 🙌🏼

Additional context

No response

Logs

03.auth-redirect.ts:45 [ERROR] 24:03.34 DEV - useQueryWrapper error Error: vue-query hooks can only be used inside setup() function or functions that support injection context.
    at useQueryClient (useQueryClient.ts:9:11)
    at useQueryWrapper (useQueryWrapper.ts:5:23)
    at wrappred (function-metrics-helpers.mjs:42:17)
    at 03.auth-redirect.ts:41:62
    at executeAsync (index.mjs:111:19)
    at 03.auth-redirect.ts:41:51
    at async router.js:138:39

Cannot seem to trigger a client validation error using Valibot/Zod

Environment

  • Nuxt 3.8.2
  • vue-query-nuxt 0.3.0
  • Tried w/ latest Node/Bun versions

Reproduction

StackBlitz reproduction

What I'm currently trying to achieve is display an error page on validation error, since, as you can see, my PostsSchema is waiting for the body to be a number, purely for testing purposes of course.

It only works when I await suspense() at the end of my script setup, or if I try/catch the parse from Valibot (same thing happens with parse from Zod) and throw a showError. createError with fatal: true is also not an option for some reason I'm not getting.

I recon I must be misunderstanding some things along the way.

Describe the bug

Shouldn't my return parse(PostsSchema, response) trigger an error, then the queryFn should do something so I'm not left with a blank page and no error feedback at all?

Additional context

No response

Logs

No response

Cannot install

Environment

Node 20.6.1
Nuxt 3.7.3

Reproduction

I followed the documentation and got this:

npm i @hebilicious/vue-query-nuxt @tanstack/vue-query
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: nuxt-app@undefined
npm ERR! Found: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@"^3.3.4" from @nuxt/[email protected]
npm ERR!   node_modules/@nuxt/vite-builder
npm ERR!     @nuxt/vite-builder@"3.7.3" from [email protected]
npm ERR!     node_modules/nuxt
npm ERR!       peer nuxt@"^3.6.5" from @nuxt/[email protected]
npm ERR!       node_modules/@nuxt/devtools
npm ERR!         dev @nuxt/devtools@"latest" from the root project
npm ERR!       2 more (@nuxt/devtools-kit, the root project)
npm ERR!   peer vue@">=2.7 || >=3" from @unhead/[email protected]
npm ERR!   node_modules/@unhead/vue
npm ERR!     @unhead/vue@"^1.7.2" from [email protected]
npm ERR!     node_modules/nuxt
npm ERR!       peer nuxt@"^3.6.5" from @nuxt/[email protected]
npm ERR!       node_modules/@nuxt/devtools
npm ERR!         dev @nuxt/devtools@"latest" from the root project
npm ERR!       2 more (@nuxt/devtools-kit, the root project)
npm ERR!   6 more (@vitejs/plugin-vue, @vitejs/plugin-vue-jsx, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! @hebilicious/vue-query-nuxt@"*" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@">= 2.5 < 2.7" from @vue/[email protected]
npm ERR!   node_modules/@vue/composition-api
npm ERR!     peerOptional @vue/composition-api@"^1.1.2" from @tanstack/[email protected]
npm ERR!     node_modules/@tanstack/vue-query
npm ERR!       @tanstack/vue-query@"*" from the root project
npm ERR!       1 more (@hebilicious/vue-query-nuxt)
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! 
npm ERR! For a full report see:
npm ERR! /Users/stefan/.npm/_logs/2023-09-15T11_11_57_116Z-eresolve-report.txt

Describe the bug

It was not possible for me to install the plugin according to the documentation.

Additional context

No response

Logs

No response

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update all non-major dependencies (@tanstack/vue-query, @types/node)

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

bun
package.json
  • @hebilicious/eslint-config 0.0.3-beta.3
  • @nuxt/test-utils ^3.12.0
  • @types/node 20.12.2
  • bumpp ^9.4.0
  • bun-types ^1.1.0
  • conventional-changelog-cli ^4.1.0
  • eslint 8.57.0
  • eslint-plugin-import ^2.29.1
  • lint-staged ^15.2.2
  • pnpm 8.15.6
  • prettier ^3.2.5
  • rimraf ^5.0.5
  • simple-git-hooks ^2.11.1
  • taze ^0.13.3
  • typescript ^5.4.3
  • vitest ^1.4.0
github-actions
.github/workflows/ci.yaml
  • actions/checkout v4
  • oven-sh/setup-bun v1
  • actions/checkout v4
  • oven-sh/setup-bun v1
.github/workflows/release.yaml
  • actions/checkout v4
  • oven-sh/setup-bun v1
npm
docs/package.json
  • @nuxt-themes/docus ^1.15.0
  • nuxt ^3.11.1
packages/vue-query-nuxt/package.json
  • @nuxt/kit ^3.11.1
  • defu ^6.1.4
  • esbuild ^0.20.2
  • magicast ^0.3.3
  • @nuxt/module-builder ^0.5.5
  • @tanstack/vue-query ^5.28.9
  • nuxt ^3.11.1
playgrounds/advanced/package.json
  • @tanstack/vue-query ^5.28.9
  • @wundergraph/vue-query ^0.2.31
  • @nuxt/devtools ^1.1.5
  • nuxt ^3.11.1
playgrounds/simple/package.json
  • @tanstack/vue-query ^5.28.9
  • nuxt ^3.11.1
playgrounds/wagmi/package.json
  • @tanstack/vue-query 5.28.9
  • @use-wagmi/nuxt ^1.1.8
  • nuxt ^3.11.1
  • use-wagmi ^0.4.10
  • viem ^1.21.4

  • Check this box to trigger a request for Renovate to run again on this repository

Suggestions

This looks great! A few suggestions:

  1. it might be worth using addTemplate rather than the current custom writeFile implementation. It supports write: true option if you need it written to disk, and it will create it within .nuxt by default.
  2. The same is true for your augmentation of types/plugins.d.ts. You can write a custom type declaration file with addTemplate and then use the prepare:types hook to add a reference to this declaration file to the Nuxt types.
  3. Instead of manually being in charge of re-writing the file when config changes you can use the updateTemplates utility provided by kit.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.