📖 Scenario: You are building a simple Vue 3 app that renders a list of fruits on the server and then hydrates it on the client. This means the HTML is generated on the server first, and then Vue takes over on the client to make it interactive without re-rendering everything.
🎯 Goal: Create a Vue 3 component that displays a list of fruits rendered on the server, then add a button to add a new fruit on the client side. This will demonstrate hydration behavior where the server-rendered HTML is reused and enhanced on the client.
📋 What You'll Learn
Create a Vue 3 component with a reactive list of fruits
Initialize the fruits list with exactly these items: 'Apple', 'Banana', 'Cherry'
Add a reactive variable called 'newFruit' initialized as an empty string
Add an input field bound to 'newFruit' and a button to add it to the fruits list
Use Vue 3 Composition API with
Ensure the component structure supports hydration (no client-only rendering)
Use semantic HTML elements and accessible labels
💡 Why This Matters
🌍 Real World
Server-side rendering with hydration is common in modern web apps to improve performance and SEO. This project shows how Vue 3 handles hydration by reusing server-rendered HTML and adding client-side interactivity.
💼 Career
Understanding hydration is important for frontend developers working with frameworks like Vue, React, or Next.js. It helps build fast, SEO-friendly apps that feel responsive and dynamic.
Progress0 / 4 steps
1
Set up the initial fruits list
Create a Vue 3 component using <script setup>. Inside it, create a reactive variable called fruits initialized with the array ["Apple", "Banana", "Cherry"]. This will represent the server-rendered data.
Vue
Hint
Use ref from Vue to create a reactive array called fruits with the given items.
2
Add a reactive variable for new fruit input
Add a reactive variable called newFruit initialized as an empty string "" inside the <script setup> block. This will hold the value typed by the user before adding it to the list.
Vue
Hint
Use ref to create a reactive string variable called newFruit initialized to an empty string.
3
Render the fruits list and input controls
In the <template>, add an unordered list <ul> that uses v-for with fruit and index to render each item in fruits. Below it, add an <input> bound with v-model to newFruit and a <button> with the label "Add Fruit".
Vue
Hint
Use v-for to loop over fruits and display each fruit inside a <li>. Bind the input with v-model to newFruit. Add a button with the text "Add Fruit".
4
Add functionality to add new fruits
Add a function called addFruit inside <script setup> that pushes the trimmed newFruit value into fruits if it is not empty, then clears newFruit. Bind this function to the button's @click event in the template.
Vue
Hint
Define addFruit to add the trimmed newFruit to fruits if not empty, then reset newFruit. Bind it to the button's click event.
Practice
(1/5)
1. What is the main purpose of hydration in Vue when using server-side rendering?
easy
A. To connect the static HTML from the server with Vue's client-side code for interactivity
B. To generate HTML on the client without any server involvement
C. To replace all server-rendered HTML with new client-rendered HTML
D. To disable JavaScript on the client for faster loading
Solution
Step 1: Understand hydration concept
Hydration links the server-rendered HTML with Vue's client code to make the page interactive without re-rendering everything.
Step 2: Compare options
To connect the static HTML from the server with Vue's client-side code for interactivity correctly describes hydration. Options B, C, and D misunderstand hydration's role.
Final Answer:
To connect the static HTML from the server with Vue's client-side code for interactivity -> Option A
Quick Check:
Hydration = connect server HTML + client code [OK]
Hint: Hydration links server HTML to client Vue code [OK]
Common Mistakes:
Thinking hydration generates HTML only on client
Believing hydration replaces server HTML entirely
Assuming hydration disables JavaScript
2. Which of the following Vue code snippets correctly enables hydration for a server-rendered app?
easy
A. createApp(App).mount('#app')
B. new Vue({ el: '#app' })
C. createSSRApp(App).mount('#app')
D. Vue.hydrate(App, '#app')
Solution
Step 1: Identify hydration method in Vue 3 SSR
Vue 3 uses createSSRApp() to create an app that supports hydration of server-rendered HTML.
Step 2: Evaluate options
createSSRApp(App).mount('#app') uses createSSRApp(). createApp(App).mount('#app') is for client-only apps. new Vue({ el: '#app' }) is Vue 2 syntax. Vue.hydrate(App, '#app') is invalid.
Final Answer:
createSSRApp(App).mount('#app') -> Option C
Quick Check:
SSR hydration uses createSSRApp() [OK]
Hint: Use createSSRApp() for hydration in Vue 3 SSR [OK]
Common Mistakes:
Using createApp() instead of createSSRApp() for hydration
Using Vue 2 syntax in Vue 3 projects
Assuming Vue has a hydrate() method
3. Given this Vue 3 SSR hydration code snippet, what will be the console output?
A. No output because mounted is not called during hydration
B. Mounted with count: 0
C. Error: createSSRApp is not a function
D. Mounted with count: undefined
Solution
Step 1: Understand mounted hook during hydration
During hydration, the mounted hook runs after the client connects to server HTML, so it logs the current data state.
Step 2: Check data initialization
Data count is initialized to 0, so the console logs 'Mounted with count: 0'.
Final Answer:
Mounted with count: 0 -> Option B
Quick Check:
Mounted logs count 0 during hydration [OK]
Hint: Mounted runs after hydration with initialized data [OK]
Common Mistakes:
Thinking mounted does not run during hydration
Assuming data is undefined at mount
Confusing createSSRApp with createApp
4. You notice that after hydration, your Vue app's client-side interactivity is broken and console shows a mismatch warning. What is the most likely cause?
medium
A. The server-rendered HTML does not match the client-side template output
B. You forgot to import Vue in your client entry file
C. You used createApp() instead of createSSRApp() on the server
D. The mounted hook is missing in your component
Solution
Step 1: Understand hydration mismatch warning
Vue warns when server HTML and client render output differ, causing hydration failure.
Step 2: Analyze options
The server-rendered HTML does not match the client-side template output correctly identifies mismatch as cause. You forgot to import Vue in your client entry file causes import errors, not mismatch. You used createApp() instead of createSSRApp() on the server is about server setup, not client mismatch. The mounted hook is missing in your component does not cause hydration mismatch.
Final Answer:
The server-rendered HTML does not match the client-side template output -> Option A
Quick Check:
Mismatch = server HTML ≠ client template [OK]
Hint: Mismatch warning means server and client HTML differ [OK]
Common Mistakes:
Ignoring mismatch warnings
Confusing import errors with hydration issues
Assuming missing mounted hook breaks hydration
5. You have a Vue 3 SSR app that renders a list of items on the server. Some items have a dynamic property that changes on the client only. How should you handle hydration to avoid mismatch errors?
hard
A. Ignore mismatch warnings since they don't affect user experience
B. Render all dynamic properties on the server to keep HTML identical
C. Disable hydration and fully re-render on client with createApp()
D. Use v-if or v-show to conditionally render client-only parts after hydration
Dynamic properties that differ between server and client cause hydration mismatches.
Step 2: Use conditional rendering for client-only parts
Using v-if or v-show to render client-only content after hydration avoids mismatch.
Step 3: Evaluate other options
Render all dynamic properties on the server to keep HTML identical is impractical if data is truly client-only. Disable hydration and fully re-render on client with createApp() disables hydration benefits. Ignore mismatch warnings since they don't affect user experience ignores errors.
Final Answer:
Use v-if or v-show to conditionally render client-only parts after hydration -> Option D
Quick Check:
Client-only content = conditional render after hydration [OK]
Hint: Render client-only parts conditionally after hydration [OK]
Common Mistakes:
Trying to render client-only data on server
Disabling hydration unnecessarily
Ignoring mismatch warnings
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.