[{"data":1,"prerenderedAt":1212},["ShallowReactive",2],{"en-post-\u002Fen\u002Fvue-query-ref-value-trap-nuxt3":3},{"id":4,"title":5,"body":6,"description":1203,"extension":1204,"meta":1205,"navigation":640,"path":1207,"seo":1208,"sitemap":1209,"stem":1210,"__hash__":1211},"blogEn\u002Fen\u002Fvue-query-ref-value-trap-nuxt3.md","Why Your Vue Query Data Doesn't Show Up in Nuxt 3 (the ref unwrapping trap)",{"type":7,"value":8,"toc":1191},"minimark",[9,13,30,42,45,50,198,205,274,281,283,291,303,371,384,386,390,397,412,464,484,486,494,576,578,585,594,756,915,917,921,1150,1152,1156,1187],[10,11,5],"h1",{"id":12},"why-your-vue-query-data-doesnt-show-up-in-nuxt-3-the-ref-unwrapping-trap",[14,15,16,17,21,22],"p",{},"While wiring up ",[18,19,20],"code",{},"@tanstack\u002Fvue-query"," in a Nuxt 3 project to fetch API data, I ran into a frustrating bug: ",[23,24,25,26,29],"strong",{},"the data showed up perfectly in ",[18,27,28],{},"console.log",", but nothing rendered on the page.",[14,31,32,33,36,37,41],{},"This post covers why that happens and how Vue 3's ",[18,34,35],{},"ref"," unwrapping actually works inside templates — because the fix is one character, but understanding ",[38,39,40],"em",{},"why"," it's needed is the useful part.",[43,44],"hr",{},[46,47,49],"h2",{"id":48},"the-symptom-data-exists-but-the-screen-shows-nothing","The symptom: data exists, but the screen shows nothing",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-vue shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003Cdiv v-if=\"postsQuery.data && postsQuery.data.length > 0\">\n    \u003Cul>\n      \u003Cli v-for=\"post in postsQuery.data\" :key=\"post.id\">\n        {{ post.title }}\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fdiv>\n  \u003Cp v-else>No data.\u003C\u002Fp>\n\u003C\u002Ftemplate>\n","vue","",[18,58,59,75,97,108,135,141,151,161,171,188],{"__ignoreMap":56},[60,61,64,68,72],"span",{"class":62,"line":63},"line",1,[60,65,67],{"class":66},"sVt8B","\u003C",[60,69,71],{"class":70},"s9eBZ","template",[60,73,74],{"class":66},">\n",[60,76,78,81,84,88,91,95],{"class":62,"line":77},2,[60,79,80],{"class":66},"  \u003C",[60,82,83],{"class":70},"div",[60,85,87],{"class":86},"sScJk"," v-if",[60,89,90],{"class":66},"=",[60,92,94],{"class":93},"sZZnC","\"postsQuery.data && postsQuery.data.length > 0\"",[60,96,74],{"class":66},[60,98,100,103,106],{"class":62,"line":99},3,[60,101,102],{"class":66},"    \u003C",[60,104,105],{"class":70},"ul",[60,107,74],{"class":66},[60,109,111,114,117,120,122,125,128,130,133],{"class":62,"line":110},4,[60,112,113],{"class":66},"      \u003C",[60,115,116],{"class":70},"li",[60,118,119],{"class":86}," v-for",[60,121,90],{"class":66},[60,123,124],{"class":93},"\"post in postsQuery.data\"",[60,126,127],{"class":86}," :key",[60,129,90],{"class":66},[60,131,132],{"class":93},"\"post.id\"",[60,134,74],{"class":66},[60,136,138],{"class":62,"line":137},5,[60,139,140],{"class":66},"        {{ post.title }}\n",[60,142,144,147,149],{"class":62,"line":143},6,[60,145,146],{"class":66},"      \u003C\u002F",[60,148,116],{"class":70},[60,150,74],{"class":66},[60,152,154,157,159],{"class":62,"line":153},7,[60,155,156],{"class":66},"    \u003C\u002F",[60,158,105],{"class":70},[60,160,74],{"class":66},[60,162,164,167,169],{"class":62,"line":163},8,[60,165,166],{"class":66},"  \u003C\u002F",[60,168,83],{"class":70},[60,170,74],{"class":66},[60,172,174,176,178,181,184,186],{"class":62,"line":173},9,[60,175,80],{"class":66},[60,177,14],{"class":70},[60,179,180],{"class":86}," v-else",[60,182,183],{"class":66},">No data.\u003C\u002F",[60,185,14],{"class":70},[60,187,74],{"class":66},[60,189,191,194,196],{"class":62,"line":190},10,[60,192,193],{"class":66},"\u003C\u002F",[60,195,71],{"class":70},[60,197,74],{"class":66},[14,199,200,201,204],{},"This looks completely reasonable. And ",[18,202,203],{},"console.log(postsQuery.data)"," confirms the data is really there:",[51,206,210],{"className":207,"code":208,"language":209,"meta":56,"style":56},"language-json shiki shiki-themes github-light github-dark","[\n  { \"id\": 1, \"title\": \"Hello Vue Query\" },\n  { \"id\": 2, \"title\": \"Nuxt 3 is Awesome\" }\n]\n","json",[18,211,212,217,246,269],{"__ignoreMap":56},[60,213,214],{"class":62,"line":63},[60,215,216],{"class":66},"[\n",[60,218,219,222,226,229,232,235,238,240,243],{"class":62,"line":77},[60,220,221],{"class":66},"  { ",[60,223,225],{"class":224},"sj4cs","\"id\"",[60,227,228],{"class":66},": ",[60,230,231],{"class":224},"1",[60,233,234],{"class":66},", ",[60,236,237],{"class":224},"\"title\"",[60,239,228],{"class":66},[60,241,242],{"class":93},"\"Hello Vue Query\"",[60,244,245],{"class":66}," },\n",[60,247,248,250,252,254,257,259,261,263,266],{"class":62,"line":99},[60,249,221],{"class":66},[60,251,225],{"class":224},[60,253,228],{"class":66},[60,255,256],{"class":224},"2",[60,258,234],{"class":66},[60,260,237],{"class":224},[60,262,228],{"class":66},[60,264,265],{"class":93},"\"Nuxt 3 is Awesome\"",[60,267,268],{"class":66}," }\n",[60,270,271],{"class":62,"line":110},[60,272,273],{"class":66},"]\n",[14,275,276,277,280],{},"But the page only ever shows ",[23,278,279],{},"\"No data.\""," Why?",[43,282],{},[46,284,286,287,290],{"id":285},"root-cause-usequery-returns-refs-not-plain-values","Root cause: ",[18,288,289],{},"useQuery()"," returns refs, not plain values",[14,292,293,296,297,299,300,302],{},[18,294,295],{},"vue-query","'s ",[18,298,289],{}," is built on Vue's reactivity system, and every property it returns is a ",[18,301,35],{},":",[304,305,306,322],"table",{},[307,308,309],"thead",{},[310,311,312,316,319],"tr",{},[313,314,315],"th",{},"Property",[313,317,318],{},"Meaning",[313,320,321],{},"Type",[323,324,325,341,356],"tbody",{},[310,326,327,333,336],{},[328,329,330],"td",{},[18,331,332],{},"data",[328,334,335],{},"Query result",[328,337,338],{},[18,339,340],{},"Ref\u003CT>",[310,342,343,348,351],{},[328,344,345],{},[18,346,347],{},"isLoading",[328,349,350],{},"Loading state",[328,352,353],{},[18,354,355],{},"Ref\u003Cboolean>",[310,357,358,363,366],{},[328,359,360],{},[18,361,362],{},"error",[328,364,365],{},"Error info",[328,367,368],{},[18,369,370],{},"Ref\u003CError>",[14,372,373,374,377,378,383],{},"So ",[18,375,376],{},"postsQuery.data"," is not an array — it's a ",[23,379,380],{},[18,381,382],{},"Ref\u003CArray>",".",[43,385],{},[46,387,389],{"id":388},"the-actual-bug-template-auto-unwrapping-doesnt-apply-inside-directives","The actual bug: template auto-unwrapping doesn't apply inside directives",[14,391,392,393,396],{},"Vue 3 templates automatically unwrap top-level refs, which is why ",[18,394,395],{},"{{ postsQuery.data }}"," \"just works\" in interpolation.",[14,398,399,400,403,404,407,408,411],{},"But that auto-unwrapping does ",[23,401,402],{},"not"," apply inside directive expressions like ",[18,405,406],{},"v-if"," and ",[18,409,410],{},"v-for",". This means the following silently does nothing useful:",[51,413,415],{"className":53,"code":414,"language":55,"meta":56,"style":56},"\u003C!-- Broken -->\n\u003Cdiv v-if=\"postsQuery.data && postsQuery.data.length > 0\"> ... \u003C\u002Fdiv>\n",[18,416,417,423],{"__ignoreMap":56},[60,418,419],{"class":62,"line":63},[60,420,422],{"class":421},"sJ8bj","\u003C!-- Broken -->\n",[60,424,425,427,429,432,434,437,440,443,446,449,452,455,457,460,462],{"class":62,"line":77},[60,426,67],{"class":66},[60,428,83],{"class":70},[60,430,87],{"class":431},"szBVR",[60,433,90],{"class":66},[60,435,436],{"class":93},"\"",[60,438,439],{"class":66},"postsQuery.data ",[60,441,442],{"class":431},"&&",[60,444,445],{"class":66}," postsQuery.data.",[60,447,448],{"class":224},"length",[60,450,451],{"class":431}," >",[60,453,454],{"class":224}," 0",[60,456,436],{"class":93},[60,458,459],{"class":66},"> ... \u003C\u002F",[60,461,83],{"class":70},[60,463,74],{"class":66},[14,465,466,468,469,471,472,475,476,479,480,483],{},[18,467,376],{}," is still a ",[18,470,35],{}," object here, so ",[18,473,474],{},".length"," is ",[18,477,478],{},"undefined",", and the condition evaluates to ",[18,481,482],{},"false"," — every time, regardless of whether data actually arrived.",[43,485],{},[46,487,489,490,493],{"id":488},"the-fix-access-value-explicitly","The fix: access ",[18,491,492],{},".value"," explicitly",[51,495,497],{"className":53,"code":496,"language":55,"meta":56,"style":56},"\u003C!-- Fixed -->\n\u003Cdiv v-if=\"postsQuery.data?.value?.length > 0\">\n  \u003Cul>\n    \u003Cli v-for=\"post in postsQuery.data.value\" :key=\"post.id\">\n      {{ post.title }}\n    \u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fdiv>\n\u003Cp v-else>No data.\u003C\u002Fp>\n",[18,498,499,504,529,534,539,544,549,554,562],{"__ignoreMap":56},[60,500,501],{"class":62,"line":63},[60,502,503],{"class":421},"\u003C!-- Fixed -->\n",[60,505,506,508,510,512,514,516,519,521,523,525,527],{"class":62,"line":77},[60,507,67],{"class":66},[60,509,83],{"class":70},[60,511,87],{"class":431},[60,513,90],{"class":66},[60,515,436],{"class":93},[60,517,518],{"class":66},"postsQuery.data?.value?.",[60,520,448],{"class":224},[60,522,451],{"class":431},[60,524,454],{"class":224},[60,526,436],{"class":93},[60,528,74],{"class":66},[60,530,531],{"class":62,"line":99},[60,532,533],{"class":66},"  \u003Cul>\n",[60,535,536],{"class":62,"line":110},[60,537,538],{"class":66},"    \u003Cli v-for=\"post in postsQuery.data.value\" :key=\"post.id\">\n",[60,540,541],{"class":62,"line":137},[60,542,543],{"class":66},"      {{ post.title }}\n",[60,545,546],{"class":62,"line":143},[60,547,548],{"class":66},"    \u003C\u002Fli>\n",[60,550,551],{"class":62,"line":153},[60,552,553],{"class":66},"  \u003C\u002Ful>\n",[60,555,556,558,560],{"class":62,"line":163},[60,557,193],{"class":66},[60,559,83],{"class":70},[60,561,74],{"class":66},[60,563,564,566,568,570,572,574],{"class":62,"line":173},[60,565,67],{"class":66},[60,567,14],{"class":70},[60,569,180],{"class":431},[60,571,183],{"class":66},[60,573,14],{"class":70},[60,575,74],{"class":66},[43,577],{},[46,579,581,582],{"id":580},"cleaner-version-pull-it-into-a-computed","Cleaner version: pull it into a ",[18,583,584],{},"computed",[14,586,587,588,590,591,593],{},"Repeating ",[18,589,492],{}," everywhere in the template gets noisy fast. Extracting it into a ",[18,592,584],{}," keeps things readable:",[51,595,599],{"className":596,"code":597,"language":598,"meta":56,"style":56},"language-ts shiki shiki-themes github-light github-dark","\u003Cscript setup>\nimport { usePosts } from '~\u002Fcomposables\u002FusePosts'\nimport { computed } from 'vue'\n\nconst { fetchPostsQuery } = usePosts()\nconst postsQuery = fetchPostsQuery()\n\nconst posts = computed(() => postsQuery.data.value ?? [])\nconst isLoading = computed(() => postsQuery.isLoading.value)\nconst error = computed(() => postsQuery.error.value)\n\u003C\u002Fscript>\n","ts",[18,600,601,610,624,636,642,664,679,683,710,728,746],{"__ignoreMap":56},[60,602,603,605,608],{"class":62,"line":63},[60,604,67],{"class":431},[60,606,607],{"class":66},"script setup",[60,609,74],{"class":431},[60,611,612,615,618,621],{"class":62,"line":77},[60,613,614],{"class":431},"import",[60,616,617],{"class":66}," { usePosts } ",[60,619,620],{"class":431},"from",[60,622,623],{"class":93}," '~\u002Fcomposables\u002FusePosts'\n",[60,625,626,628,631,633],{"class":62,"line":99},[60,627,614],{"class":431},[60,629,630],{"class":66}," { computed } ",[60,632,620],{"class":431},[60,634,635],{"class":93}," 'vue'\n",[60,637,638],{"class":62,"line":110},[60,639,641],{"emptyLinePlaceholder":640},true,"\n",[60,643,644,647,650,653,656,658,661],{"class":62,"line":137},[60,645,646],{"class":431},"const",[60,648,649],{"class":66}," { ",[60,651,652],{"class":224},"fetchPostsQuery",[60,654,655],{"class":66}," } ",[60,657,90],{"class":431},[60,659,660],{"class":86}," usePosts",[60,662,663],{"class":66},"()\n",[60,665,666,668,671,674,677],{"class":62,"line":143},[60,667,646],{"class":431},[60,669,670],{"class":224}," postsQuery",[60,672,673],{"class":431}," =",[60,675,676],{"class":86}," fetchPostsQuery",[60,678,663],{"class":66},[60,680,681],{"class":62,"line":153},[60,682,641],{"emptyLinePlaceholder":640},[60,684,685,687,690,692,695,698,701,704,707],{"class":62,"line":163},[60,686,646],{"class":431},[60,688,689],{"class":224}," posts",[60,691,673],{"class":431},[60,693,694],{"class":86}," computed",[60,696,697],{"class":66},"(() ",[60,699,700],{"class":431},"=>",[60,702,703],{"class":66}," postsQuery.data.value ",[60,705,706],{"class":431},"??",[60,708,709],{"class":66}," [])\n",[60,711,712,714,717,719,721,723,725],{"class":62,"line":173},[60,713,646],{"class":431},[60,715,716],{"class":224}," isLoading",[60,718,673],{"class":431},[60,720,694],{"class":86},[60,722,697],{"class":66},[60,724,700],{"class":431},[60,726,727],{"class":66}," postsQuery.isLoading.value)\n",[60,729,730,732,735,737,739,741,743],{"class":62,"line":190},[60,731,646],{"class":431},[60,733,734],{"class":224}," error",[60,736,673],{"class":431},[60,738,694],{"class":86},[60,740,697],{"class":66},[60,742,700],{"class":431},[60,744,745],{"class":66}," postsQuery.error.value)\n",[60,747,749,751,754],{"class":62,"line":748},11,[60,750,193],{"class":431},[60,752,753],{"class":66},"script",[60,755,74],{"class":431},[51,757,759],{"className":53,"code":758,"language":55,"meta":56,"style":56},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp v-if=\"isLoading\">Loading...\u003C\u002Fp>\n    \u003Cp v-else-if=\"error\">Error: {{ error.message }}\u003C\u002Fp>\n    \u003Cdiv v-else-if=\"posts.length > 0\">\n      \u003Cul>\n        \u003Cli v-for=\"post in posts\" :key=\"post.id\">{{ post.title }}\u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n    \u003Cp v-else>No data.\u003C\u002Fp>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[18,760,761,769,777,797,818,833,841,868,876,884,898,906],{"__ignoreMap":56},[60,762,763,765,767],{"class":62,"line":63},[60,764,67],{"class":66},[60,766,71],{"class":70},[60,768,74],{"class":66},[60,770,771,773,775],{"class":62,"line":77},[60,772,80],{"class":66},[60,774,83],{"class":70},[60,776,74],{"class":66},[60,778,779,781,783,785,787,790,793,795],{"class":62,"line":99},[60,780,102],{"class":66},[60,782,14],{"class":70},[60,784,87],{"class":86},[60,786,90],{"class":66},[60,788,789],{"class":93},"\"isLoading\"",[60,791,792],{"class":66},">Loading...\u003C\u002F",[60,794,14],{"class":70},[60,796,74],{"class":66},[60,798,799,801,803,806,808,811,814,816],{"class":62,"line":110},[60,800,102],{"class":66},[60,802,14],{"class":70},[60,804,805],{"class":86}," v-else-if",[60,807,90],{"class":66},[60,809,810],{"class":93},"\"error\"",[60,812,813],{"class":66},">Error: {{ error.message }}\u003C\u002F",[60,815,14],{"class":70},[60,817,74],{"class":66},[60,819,820,822,824,826,828,831],{"class":62,"line":137},[60,821,102],{"class":66},[60,823,83],{"class":70},[60,825,805],{"class":86},[60,827,90],{"class":66},[60,829,830],{"class":93},"\"posts.length > 0\"",[60,832,74],{"class":66},[60,834,835,837,839],{"class":62,"line":143},[60,836,113],{"class":66},[60,838,105],{"class":70},[60,840,74],{"class":66},[60,842,843,846,848,850,852,855,857,859,861,864,866],{"class":62,"line":153},[60,844,845],{"class":66},"        \u003C",[60,847,116],{"class":70},[60,849,119],{"class":86},[60,851,90],{"class":66},[60,853,854],{"class":93},"\"post in posts\"",[60,856,127],{"class":86},[60,858,90],{"class":66},[60,860,132],{"class":93},[60,862,863],{"class":66},">{{ post.title }}\u003C\u002F",[60,865,116],{"class":70},[60,867,74],{"class":66},[60,869,870,872,874],{"class":62,"line":163},[60,871,146],{"class":66},[60,873,105],{"class":70},[60,875,74],{"class":66},[60,877,878,880,882],{"class":62,"line":173},[60,879,156],{"class":66},[60,881,83],{"class":70},[60,883,74],{"class":66},[60,885,886,888,890,892,894,896],{"class":62,"line":190},[60,887,102],{"class":66},[60,889,14],{"class":70},[60,891,180],{"class":86},[60,893,183],{"class":66},[60,895,14],{"class":70},[60,897,74],{"class":66},[60,899,900,902,904],{"class":62,"line":748},[60,901,166],{"class":66},[60,903,83],{"class":70},[60,905,74],{"class":66},[60,907,909,911,913],{"class":62,"line":908},12,[60,910,193],{"class":66},[60,912,71],{"class":70},[60,914,74],{"class":66},[43,916],{},[46,918,920],{"id":919},"the-composable-behind-it","The composable behind it",[51,922,924],{"className":596,"code":923,"language":598,"meta":56,"style":56},"\u002F\u002F ~\u002Fcomposables\u002FusePosts.ts\nimport { useNuxtApp } from '#app'\n\nexport const usePostApi = () => {\n  const axios = useNuxtApp().$axios\n  return {\n    fetchPosts: async () => {\n      const response = await axios.get('\u002Fposts')\n      return response.data\n    }\n  }\n}\n\nexport const usePosts = () => {\n  const api = usePostApi()\n  const fetchPostsQuery = () => useQuery({\n    queryKey: ['posts'],\n    queryFn: api.fetchPosts\n  })\n  return { fetchPostsQuery }\n}\n",[18,925,926,931,943,947,968,984,991,1007,1035,1043,1048,1053,1058,1063,1080,1094,1113,1125,1131,1137,1145],{"__ignoreMap":56},[60,927,928],{"class":62,"line":63},[60,929,930],{"class":421},"\u002F\u002F ~\u002Fcomposables\u002FusePosts.ts\n",[60,932,933,935,938,940],{"class":62,"line":77},[60,934,614],{"class":431},[60,936,937],{"class":66}," { useNuxtApp } ",[60,939,620],{"class":431},[60,941,942],{"class":93}," '#app'\n",[60,944,945],{"class":62,"line":99},[60,946,641],{"emptyLinePlaceholder":640},[60,948,949,952,955,958,960,963,965],{"class":62,"line":110},[60,950,951],{"class":431},"export",[60,953,954],{"class":431}," const",[60,956,957],{"class":86}," usePostApi",[60,959,673],{"class":431},[60,961,962],{"class":66}," () ",[60,964,700],{"class":431},[60,966,967],{"class":66}," {\n",[60,969,970,973,976,978,981],{"class":62,"line":137},[60,971,972],{"class":431},"  const",[60,974,975],{"class":224}," axios",[60,977,673],{"class":431},[60,979,980],{"class":86}," useNuxtApp",[60,982,983],{"class":66},"().$axios\n",[60,985,986,989],{"class":62,"line":143},[60,987,988],{"class":431},"  return",[60,990,967],{"class":66},[60,992,993,996,998,1001,1003,1005],{"class":62,"line":153},[60,994,995],{"class":86},"    fetchPosts",[60,997,228],{"class":66},[60,999,1000],{"class":431},"async",[60,1002,962],{"class":66},[60,1004,700],{"class":431},[60,1006,967],{"class":66},[60,1008,1009,1012,1015,1017,1020,1023,1026,1029,1032],{"class":62,"line":163},[60,1010,1011],{"class":431},"      const",[60,1013,1014],{"class":224}," response",[60,1016,673],{"class":431},[60,1018,1019],{"class":431}," await",[60,1021,1022],{"class":66}," axios.",[60,1024,1025],{"class":86},"get",[60,1027,1028],{"class":66},"(",[60,1030,1031],{"class":93},"'\u002Fposts'",[60,1033,1034],{"class":66},")\n",[60,1036,1037,1040],{"class":62,"line":173},[60,1038,1039],{"class":431},"      return",[60,1041,1042],{"class":66}," response.data\n",[60,1044,1045],{"class":62,"line":190},[60,1046,1047],{"class":66},"    }\n",[60,1049,1050],{"class":62,"line":748},[60,1051,1052],{"class":66},"  }\n",[60,1054,1055],{"class":62,"line":908},[60,1056,1057],{"class":66},"}\n",[60,1059,1061],{"class":62,"line":1060},13,[60,1062,641],{"emptyLinePlaceholder":640},[60,1064,1066,1068,1070,1072,1074,1076,1078],{"class":62,"line":1065},14,[60,1067,951],{"class":431},[60,1069,954],{"class":431},[60,1071,660],{"class":86},[60,1073,673],{"class":431},[60,1075,962],{"class":66},[60,1077,700],{"class":431},[60,1079,967],{"class":66},[60,1081,1083,1085,1088,1090,1092],{"class":62,"line":1082},15,[60,1084,972],{"class":431},[60,1086,1087],{"class":224}," api",[60,1089,673],{"class":431},[60,1091,957],{"class":86},[60,1093,663],{"class":66},[60,1095,1097,1099,1101,1103,1105,1107,1110],{"class":62,"line":1096},16,[60,1098,972],{"class":431},[60,1100,676],{"class":86},[60,1102,673],{"class":431},[60,1104,962],{"class":66},[60,1106,700],{"class":431},[60,1108,1109],{"class":86}," useQuery",[60,1111,1112],{"class":66},"({\n",[60,1114,1116,1119,1122],{"class":62,"line":1115},17,[60,1117,1118],{"class":66},"    queryKey: [",[60,1120,1121],{"class":93},"'posts'",[60,1123,1124],{"class":66},"],\n",[60,1126,1128],{"class":62,"line":1127},18,[60,1129,1130],{"class":66},"    queryFn: api.fetchPosts\n",[60,1132,1134],{"class":62,"line":1133},19,[60,1135,1136],{"class":66},"  })\n",[60,1138,1140,1142],{"class":62,"line":1139},20,[60,1141,988],{"class":431},[60,1143,1144],{"class":66}," { fetchPostsQuery }\n",[60,1146,1148],{"class":62,"line":1147},21,[60,1149,1057],{"class":66},[43,1151],{},[46,1153,1155],{"id":1154},"takeaway","Takeaway",[105,1157,1158,1165,1181],{},[116,1159,1160,1162,1163,383],{},[18,1161,289],{}," returns every piece of state as a ",[18,1164,35],{},[116,1166,1167,1168,1171,1172,1174,1175,1177,1178,1180],{},"Template interpolation (",[18,1169,1170],{},"{{ }}",") auto-unwraps refs, but ",[18,1173,406],{}," \u002F ",[18,1176,410],{}," expressions do not — you need ",[18,1179,492],{}," explicitly.",[116,1182,1183,1184,1186],{},"Pulling the unwrapped values into ",[18,1185,584],{}," properties keeps the template clean and avoids this trap entirely.",[1188,1189,1190],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":56,"searchDepth":77,"depth":77,"links":1192},[1193,1194,1196,1197,1199,1201,1202],{"id":48,"depth":77,"text":49},{"id":285,"depth":77,"text":1195},"Root cause: useQuery() returns refs, not plain values",{"id":388,"depth":77,"text":389},{"id":488,"depth":77,"text":1198},"The fix: access .value explicitly",{"id":580,"depth":77,"text":1200},"Cleaner version: pull it into a computed",{"id":919,"depth":77,"text":920},{"id":1154,"depth":77,"text":1155},"Data logs fine in the console but never renders — a walkthrough of why v-if and v-for don't auto-unwrap refs returned by @tanstack\u002Fvue-query, and how to fix it.","md",{"date":1206},"2026.10.07","\u002Fen\u002Fvue-query-ref-value-trap-nuxt3",{"title":5,"description":1203},{"loc":1207},"en\u002Fvue-query-ref-value-trap-nuxt3","6trzcsz1qIAtysNFxg1stZY0d0MY_0MmwS7kLkG9wac",1791347386895]