Welcome to part four of our RESTful API series! So far, we’ve built a robust backend with Node.js, Express, and PostgreSQL, complete with AI-enhanced product descriptions using OpenAI. But an API is only half the story. Today, we’re turning our attention to the frontend, where we’ll use the power of Nuxt 3 and Pinia to create a beautiful and reactive user interface. Imagine your marketplace coming to life, where products are elegantly displayed and state management is a breeze.
Grab your coding cape, because we’re about to embark on an adventure into the world of Nuxt 3.
Step 1: Setting Up a New Nuxt 3 Project
Let’s kick things off by creating a fresh Nuxt 3 project. Open your terminal and run:
npx nuxi init nuxt-frontend
cd nuxt-frontend
npm install
This sets up a basic Nuxt 3 project. Now, let’s install the dependencies we’ll need, including Pinia for state management:
npm install @pinia/nuxt
Next, open your nuxt.config.ts
file and add Pinia to your Nuxt modules:
export default defineNuxtConfig({
modules: ['@pinia/nuxt'],
});
Now, you’re ready to harness the power of Nuxt 3 and Pinia!
2220+ FREE RESOURCES FOR DEVELOPERS!! ❤️ 😍🥳 (updated daily)
1400+ Free HTML Templates
338+ Free News Articles
64+ Free AI Prompts
303+ Free Code Libraries
51+ Free Code Snippets & Boilerplates for Node, Nuxt, Vue, and more!
25+ Free Open Source Icon Libraries
Visit dailysandbox.pro for free access to a treasure trove of resources!
Step 2: Setting Up Pinia for State Management
Create a new folder named stores
in the ~/
directory of your Nuxt project. Inside, create a file called products.js
:
import { defineStore } from 'pinia';
export const useProductsStore = defineStore('products', {
state: () => ({
products: [],
}),
actions: {
async fetchProducts() {
try {
const { data } = await useFetch('/api/products');
this.products = data.value;
} catch (error) {
console.error('Error fetching products:', error);
}
},
},
});
This Pinia store handles fetching product data from our backend API and storing it in the products
array. The useFetch()
function in Nuxt simplifies API calls, automatically handling reactivity and caching.
Step 3: Creating the Index Page to Display Products
Navigate to your pages
directory and open index.vue
. Here, we’ll set up a page that fetches and displays our products:
<script setup>
import { useProductsStore } from '~/stores/products';
const productsStore = useProductsStore();
const { products, fetchProducts } = productsStore;
onMounted(() => {
fetchProducts();
});
</script>
<template>
<div class="container">
<h1>Our Products</h1>
<div v-if="products.length === 0">Loading products...</div>
<div v-else class="products-grid">
<div v-for="product in products" :key="product.id" class="product-card">
<h2>{{ product.name }}</h2>
<p>{{ product.description }}</p>
<p><strong>Price:</strong> ${{ product.price }}</p>
</div>
</div>
</div>
</template>
<style scoped>
.container {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
}
.product-card {
border: 1px solid #ddd;
padding: 1rem;
border-radius: 8px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>
Here’s a breakdown of what’s happening:
-
Template : We use
v-for
to iterate over theproducts
array and display each product’s name, description, and price in a card layout. -
Pinia Integration : We import and use the
productsStore
from Pinia, callingfetchProducts()
when the component mounts to load our products from the backend. - Styling : A simple grid layout makes our product cards look neat and organized.
Step 4: Connecting the Frontend to Your API
By default, useFetch()
in Nuxt will make requests relative to your app’s base URL. To point it to your backend API, you can configure the base URL in your nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['@pinia/nuxt'],
runtimeConfig: {
public: {
apiBase: process.env.API_BASE || 'http://localhost:3000',
},
},
});
Now, in your Pinia store, update the useFetch
call to use this base URL:
const { data } = await useFetch(`${useRuntimeConfig().public.apiBase}/products`);
Step 5: Running Your Nuxt 3 Frontend
With everything set up, start your Nuxt 3 app:
npm run dev
Visit http://localhost:3000
in your browser, and you should see a beautifully rendered list of products, fetched dynamically from your backend. Congratulations! You’ve built a full-stack application, with a RESTful API and a sleek, modern frontend.
Why Nuxt 3 and Pinia Are a Game-Changer
- Seamless Integration : Nuxt 3’s powerful framework and Pinia’s intuitive state management work together like a well-oiled machine.
-
Reactivity and Performance :
useFetch()
handles data reactivity, caching, and server-side rendering, making your app lightning-fast. - Developer Experience : With its clean setup and helpful tooling, building with Nuxt 3 is a joy.
For more tips on web development, check out DailySandbox and sign up for our free newsletter to stay ahead of the curve!
Top comments (0)