In today’s fast-paced web development world, building full-stack applications has become a common requirement. Next.js, a popular React framework, provides an excellent solution to seamlessly create full-stack applications. It simplifies the process by integrating both front-end and back-end functionalities within a single project.
In this blog, we’ll walk you through building a full-stack application using Next.js, covering everything from the basics to creating API routes, fetching data, and deploying the app.
What is Next.js?
Next.js is a React-based framework that enables server-side rendering (SSR), static site generation (SSG), and API routes. It’s optimized for performance and supports a variety of features that make building full-stack applications easier. It allows you to combine both front-end and back-end code into one project, meaning you can handle API requests, authentication, and database interactions in one place.
Prerequisites
Before we start building our app, ensure that you have the following:
- Node.js and npm installed
- Basic knowledge of React.js and JavaScript
- Familiarity with concepts like API routes and state management
You can download and install Node.js from here.
Setting Up the Project
Let’s start by creating a new Next.js project. Open your terminal and run the following command:
npx create-next-app@latest full-stack-nextjs-app
cd full-stack-nextjs-app
Once the project is set up, you can navigate to the project folder and start the development server:
npm run dev
This will start the Next.js development server, and you can open the app in your browser at
http://localhost:3000
Building the Front-End
For the front-end, we’ll use React components to display data and interact with the user. Next.js supports both pages and components for building the UI.
Creating the Home Page
In the pages/index.js
file, let’s create a simple home page to display a list of items fetched from an API route.
// pages/index.js
import { useState, useEffect } from "react";
export default function Home() {
const [data, setData] = useState([]);
useEffect(() => {
fetch("/api/items")
.then((res) => res.json())
.then((data) => setData(data));
}, []);
return (
<div>
<h1>Full-Stack Next.js App</h1>
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
Here, we are using the useState
and useEffect
hooks to manage the application state and fetch data from an API route when the page is loaded. The fetch("/api/items")
call will fetch data from our back-end, which we’ll define next.
Creating API Routes
Next.js allows us to create API routes in the pages/api
directory. These routes will act as back-end endpoints that our front-end can call. Let’s create a simple API route that will return a list of items in JSON format.
Defining the API Route
Create a new file called items.js
in the pages/api
directory:
mkdir -p pages/api
touch pages/api/items.js
Now, open the pages/api/items.js
file and define the API route:
// pages/api/items.js
export default function handler(req, res) {
const items = [
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
{ id: 3, name: "Item 3" },
];
res.status(200).json(items);
}
This function will respond to HTTP GET requests by sending a list of items as a JSON array.
Fetching the API Data in the Front-End
In the front-end, we already set up a fetch request to get data from /api/items
. When you reload the page, you should see the list of items displayed in the UI.
Handling Dynamic Routes and Database Integration
Now let’s take things further by introducing dynamic routes and connecting the app to a database. We will use SQLite as our database to keep things simple, but you can use any database system like MySQL, PostgreSQL, or MongoDB.
Install SQLite and a database library:
First, install SQLite and Prisma (an ORM) to interact with the database.
npm install sqlite3 prisma
npx prisma init
This will create a prisma folder with a schema.prisma file. Open the schema.prisma file and configure the SQLite database:
datasource db {
provider = "sqlite"
provider = "sqlite"
url = "file:./dev.db"
}
generator client {
provider = "prisma-client-js"
}
model Item {
id Int @id @default(autoincrement())
name String
}
Migrate the database:
After updating the schema, run the migration command to create the SQLite database.
npx prisma migrate dev --name init
- This command will create the dev.db SQLite file in the prisma directory.
Creating the API Route to Fetch Data from SQLite:
Next, let’s modify our API route to fetch data from the SQLite database.
// pages/api/items.js
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default async function handler(req, res) {
const items = await prisma.item.findMany();
res.status(200).json(items);
}
- Now, this route will fetch the list of items from the SQLite database and return them as JSON.
Insert Data into the Database:
You can insert items directly into the database via Prisma’s CLI or create an admin interface for adding items. For simplicity, you can use the Prisma client to insert some sample data.
npx prisma db seed
Create a file called prisma/seed.js
and add the following code to seed the database:
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();
async function main() {
await prisma.item.createMany({
data: [
{ name: "Item 1" },
{ name: "Item 2" },
{ name: "Item 3" },
],
});
}
main()
.catch((e) => {
throw e;
})
.finally(async () => {
await prisma.$disconnect();
});
Final Touches: Styling and Deployment
To make our app more user-friendly, you can add some basic styling using CSS Modules or a CSS-in-JS library like styled-components. For deployment, you can easily deploy the app to Vercel, which is the platform created by the creators of Next.js.
- Deploying to Vercel: After setting up your app, you can deploy it by following these simple steps:
- Install the Vercel CLI:
npm install -g vercel
- Run
vercel
in the project directory and follow the prompts to deploy.
- Install the Vercel CLI:
Conclusion
In this blog, we’ve learned how to build a full-stack application using Next.js. By leveraging Next.js’s powerful features such as API routes, dynamic routing, and seamless integration with databases, we can efficiently create full-stack applications with minimal effort.
Whether you’re building a simple app or a complex one, Next.js is a fantastic choice for handling both the front-end and back-end components in a unified, easy-to-use framework.
Happy coding!
At 7Shades Digital, we specialised in creating strategies that help businesses excel in the digital world. If you’re ready to take your website to the next level, contact us today!