N
Nuxt2mo ago
Sander

useFetch typed but no typescript completions

Hi so for a specific enpoint/route I am running into a strange issue. The type completion doesn't work in the template, however when I hover over data from the useFetch call, it is typed. I don't see this for any other routes. I've tried restarting a dev server, tried reloading my VSCode window, nothing works. And the strange thing is, it's only in the page.vue file. Any suggestions are greatly appreciated
No description
No description
5 Replies
kapa.ai
kapa.ai2mo ago
Hi @Sander. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the knowledge sources, here are some suggestions and context for your issue with TypeScript completions not working in the template for a specific route, even though the type is correct when hovering over data from useFetch: 1. Ensure <script setup lang="ts"> is used
Type completions and proper TypeScript support in Vue SFCs require the lang="ts" attribute on your <script setup> tag. Omitting this can cause TypeScript and Volar to not provide completions or type checking in the template, even if types are inferred in the script section. This is a common oversight and can lead to exactly the symptoms you describe. Double-check your file for this attribute.
<script setup lang="ts">
// your code
</script>

<script setup lang="ts">
// your code
</script>

See example and explanation 2. Nuxt auto-imports and type inference
Nuxt auto-imports composables like useFetch and provides type inference for their return values. In the <script setup lang="ts">, the returned data is a Ref and should be accessed with .value. In the template, you should be able to access the unwrapped value directly. If this works in other files but not in one, it could be a local configuration or syntax issue.
Docs: Auto-imports 3. Type generation and IDE support
Nuxt generates type definitions in .nuxt/nuxt.d.ts and configures TypeScript via .nuxt/tsconfig.json. If you haven't run nuxt dev or nuxt build recently, or if these files are out of sync, type completions may not work as expected. Try stopping your dev server, deleting .nuxt, and restarting it to regenerate types.
Docs: Auto-generated Types 4. Volar and VSCode quirks
Sometimes, VSCode or Volar can get "stuck." Try: - Restarting VSCode. - Running the "TypeScript: Restart TS server" command. - Ensuring Volar is in Takeover mode and the built-in TypeScript extension is disabled for the workspace. - Deleting node_modules and reinstalling dependencies. 5. Check for file-specific issues
If the problem is isolated to one file, compare it to working files for differences in: - The presence of lang="ts". - The structure of the <script setup>. - Any unusual imports or syntax errors. If you have confirmed all of the above and the issue persists only in one file, there may be a subtle syntax or configuration issue in that file. Unfortunately, the knowledge sources do not provide a more specific solution for this exact scenario, but the above steps are the most common causes and resolutions for missing TypeScript completions in Nuxt and Vue SFCs. If you can share the problematic file's code, it may help pinpoint the issue further. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@256825598393974784> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Sander
SanderOP2mo ago
Here is the code for the index.vue
<template>
<NuxtLayout name="categories">
<template #sidebar>
<CategoriesSidebar />
</template>
<div v-if="data">
<h1>{{ data.category.name}}</h1> <-- works but no type completion

{{ categoryName }} <-- works
{{ data }}
</div>
</NuxtLayout>
</template>

<script setup lang="ts">
const route = useRoute()
const parts = Array.isArray(route.params.slug)
? route.params.slug
: [route.params.slug]
const fullSlug = parts.filter(Boolean).join('/')

const { data } = await useFetch(`/api/categories/${fullSlug}`)

const categoryName = data.value.category.name <-- no type completion
</script>
<template>
<NuxtLayout name="categories">
<template #sidebar>
<CategoriesSidebar />
</template>
<div v-if="data">
<h1>{{ data.category.name}}</h1> <-- works but no type completion

{{ categoryName }} <-- works
{{ data }}
</div>
</NuxtLayout>
</template>

<script setup lang="ts">
const route = useRoute()
const parts = Array.isArray(route.params.slug)
? route.params.slug
: [route.params.slug]
const fullSlug = parts.filter(Boolean).join('/')

const { data } = await useFetch(`/api/categories/${fullSlug}`)

const categoryName = data.value.category.name <-- no type completion
</script>
This is the api endpoint:
import { db } from '@server/db'
import { z } from 'zod'

const schema = z.object({
slug: z.string()
})

export default defineEventHandler(async (event) => {
const slugRaw = getRouterParam(event, 'slug') // 'real-estate/rentals' for catch-all
const { slug } = schema.parse({ slug: slugRaw })

const category = await db.query.category.findFirst({
where: (c, { eq }) => eq(c.fullSlug, slug)
})

if (!category) {
throw createError({
statusCode: 404,
statusMessage: 'Category not found'
})
}

return {category}
})
import { db } from '@server/db'
import { z } from 'zod'

const schema = z.object({
slug: z.string()
})

export default defineEventHandler(async (event) => {
const slugRaw = getRouterParam(event, 'slug') // 'real-estate/rentals' for catch-all
const { slug } = schema.parse({ slug: slugRaw })

const category = await db.query.category.findFirst({
where: (c, { eq }) => eq(c.fullSlug, slug)
})

if (!category) {
throw createError({
statusCode: 404,
statusMessage: 'Category not found'
})
}

return {category}
})
Data is loading fine in the page. Its just the type completion that is not working
dwol
dwol2mo ago
Won’t categoryName be undefined until the fetch completes? Could that be why? Try a computed instead of const
Sander
SanderOP2mo ago
The thing is that it also doesn't work if I just access the data.value ref in the template without assigning the value to a const. No other templates in my project have this issue tho. It's very strange

Did you find this page helpful?