📖 Scenario: You are building a simple Nuxt 3 app that shows a list of users fetched from a public API. You want to learn how to fetch data using Nuxt's useFetch and useAsyncData composables.
🎯 Goal: Create a Nuxt 3 page component that fetches user data from https://jsonplaceholder.typicode.com/users using useFetch and useAsyncData. Display the users' names in a list.
📋 What You'll Learn
Create a Nuxt 3 page component with a template and script setup
Use useFetch to fetch user data from the API
Use useAsyncData to fetch the same user data
Display the list of user names fetched by both methods separately
Ensure the component is accessible and uses semantic HTML
💡 Why This Matters
🌍 Real World
Fetching data from APIs is a common task in web apps. Nuxt 3 provides easy ways to fetch data on the server or client side using composables like useFetch and useAsyncData.
💼 Career
Understanding Nuxt data fetching is essential for frontend developers working with Vue and Nuxt frameworks to build fast, SEO-friendly web applications.
Progress0 / 4 steps
1
Setup Nuxt page and fetch users with useFetch
Create a Nuxt 3 page component with <template> and <script setup> tags. Inside the script, use useFetch to fetch data from 'https://jsonplaceholder.typicode.com/users' and store it in a variable called fetchUsers. In the template, add an unordered list that uses fetchUsers.data to display each user's name inside a <li>.
Vue
Hint
Remember to use await with useFetch inside <script setup>.
2
Add a config variable for API URL
Add a constant variable called apiUrl and set it to 'https://jsonplaceholder.typicode.com/users'. Update the useFetch call to use this apiUrl variable instead of the string URL.
Vue
Hint
Define apiUrl before calling useFetch.
3
Fetch users with useAsyncData
Below the useFetch call, add a new constant called asyncUsers. Use useAsyncData with the key 'users' and a fetch function that fetches from apiUrl and returns the JSON response. In the template, add a new section with heading Users (useAsyncData) and an unordered list that displays each user's name from asyncUsers.data.
Vue
Hint
Use await useAsyncData('users', () => fetch(apiUrl).then(res => res.json())).
4
Add accessibility and semantic improvements
Add a main container with <main> wrapping both user sections. Add aria-label attributes to each section describing the data source. Ensure each list uses semantic <ul> and <li> tags. Confirm the headings use <h2> tags for clear structure.
Vue
Hint
Wrap the two sections inside a <main> with an aria-label describing the content.
Practice
(1/5)
1. What is the main difference between useFetch and useAsyncData in Nuxt?
easy
A. useAsyncData automatically refreshes data, useFetch never does.
B. useAsyncData requires a unique key for caching, useFetch does not.
C. useFetch is only for server-side, useAsyncData is client-side only.
D. useFetch caches data with a key, useAsyncData fetches without caching.
Solution
Step 1: Understand useFetch behavior
useFetch fetches data from a URL quickly but does not require a key for caching.
Step 2: Understand useAsyncData behavior
useAsyncData needs a unique key to cache the fetched data, allowing more control over data reuse.
Final Answer:
useAsyncData requires a unique key for caching, useFetch does not. -> Option B
Quick Check:
Key caching difference = D [OK]
Hint: Remember: useAsyncData needs a key, useFetch is simpler [OK]
Common Mistakes:
Thinking useFetch caches data with keys
Confusing client/server usage of both
Assuming useAsyncData auto-refreshes data
2. Which of the following is the correct syntax to use useAsyncData in a Nuxt component?
easy
A. const { data } = useAsyncData('posts', () => $fetch('/api/posts'))
B. const data = useAsyncData('/api/posts')
C. useAsyncData(() => $fetch('posts'), 'posts')
D. const { data } = useAsyncData(() => fetch('/api/posts'))
Solution
Step 1: Check the required parameters for useAsyncData
The first parameter is a unique key string, the second is a function returning a promise.
Step 2: Validate each option's syntax
const { data } = useAsyncData('posts', () => $fetch('/api/posts')) correctly uses a key 'posts' and a fetch function with $fetch. Others miss the key or use wrong order.
Final Answer:
const { data } = useAsyncData('posts', () => $fetch('/api/posts')) -> Option A
Quick Check:
Key first, fetch function second = A [OK]
Hint: Key string first, fetch function second in useAsyncData [OK]
What will pending be initially when the component loads?
medium
A. undefined
B. false
C. true
D. null
Solution
Step 1: Understand useFetch loading state
pending is a reactive boolean indicating if the fetch is still in progress.
Step 2: Initial value of pending
When the component loads and fetch starts, pending is true until data arrives.
Final Answer:
true -> Option C
Quick Check:
Loading state pending = true [OK]
Hint: pending is true while fetching data [OK]
Common Mistakes:
Assuming pending is false initially
Confusing pending with data presence
Expecting pending to be null or undefined
4. You wrote this code in a Nuxt component:
const { data } = useAsyncData(() => $fetch('/api/items'))
But the data never loads. What is the likely problem?
medium
A. Using $fetch instead of native fetch.
B. Returning data directly instead of inside a function.
C. Not awaiting the useAsyncData call.
D. Missing a unique key as the first argument to useAsyncData.
Solution
Step 1: Check useAsyncData parameters
useAsyncData requires a unique key string as the first argument for caching.
Step 2: Identify missing key issue
Omitting the key causes the fetch not to run properly or cache data, so data never loads.
Final Answer:
Missing a unique key as the first argument to useAsyncData. -> Option D
Quick Check:
Key missing in useAsyncData = B [OK]
Hint: Always provide a key string first in useAsyncData [OK]
Common Mistakes:
Skipping the key argument
Confusing $fetch with fetch as cause
Expecting useAsyncData to be awaited
5. You want to fetch user data and posts in a Nuxt page using useAsyncData. You want posts to refresh every time the user ID changes. Which approach correctly achieves this?
hard
A. Use useAsyncData with a key including the user ID, e.g., useAsyncData(`posts-${userId}`, () => $fetch(`/api/posts?user=${userId}`)).
B. Use useAsyncData with a fixed key 'posts' and rely on automatic refresh.
C. Use useFetch instead of useAsyncData because it auto-refreshes on param change.
D. Call useAsyncData without a key and manually watch userId to refetch.
Solution
Step 1: Understand caching with keys in useAsyncData
Keys uniquely identify cached data. Changing the key triggers a new fetch.
Step 2: Use dynamic key with user ID
Including userId in the key string ensures posts refetch when userId changes.
Step 3: Evaluate other options
Fixed keys won't refresh; useFetch doesn't auto-refresh on param change; manual watch is more complex.
Final Answer:
Use useAsyncData with a key including the user ID, e.g., useAsyncData(`posts-${userId}`, () => $fetch(`/api/posts?user=${userId}`)). -> Option A
Quick Check:
Dynamic key triggers refetch = C [OK]
Hint: Include changing params in key string for refetch [OK]
Common Mistakes:
Using fixed keys expecting auto-refresh
Assuming useFetch auto-refreshes on param change
Skipping key causes no caching or refetch
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.