The web is changing again. Web2 gave us apps that connect billions of people, but most of those apps run on centralized servers controlled by a handful of companies. Web3 flips this model on its head. Instead of trusting big corporations to manage your data and transactions, Web3 apps (often referred to as dApps) rely on decentralized networks like Ethereum, Polygon, or Solana.
Next.js, already one of the most popular React frameworks, is becoming a natural fit for building Web3 frontends. It provides performance, flexibility, and developer experience that pairs well with blockchain APIs. If you are curious about how Web3 and Next.js come together, this article will guide you through the key concepts and practical steps.
Why Next.js for Web3?
Next.js is designed for modern web applications. Features such as server-side rendering, API routes, and static site generation make it a solid choice for projects that require scalability. When working with Web3, these strengths matter because:
Speed and SEO: Blockchain apps need user trust. Fast-loading pages and good search rankings help attract and retain users.
Serverless API routes: With Next.js, you can create backend logic without spinning up a separate server, which is useful for things like off-chain computations.
Flexibility with rendering: You can choose between static generation, server-side rendering, or client-side rendering depending on your dApp’s needs.
Setting Up Next.js with Web3
The first step is creating a Next.js project. If you do not already have one, run:
npx create-next-app@latest web3-dapp
cd web3-dapp
Next, install ethers.js, a popular library for interacting with Ethereum:
npm install ethers
Connecting to MetaMask
Most dApps start with a simple feature: connecting a wallet. MetaMask is the most widely used wallet for Ethereum-based apps. Here is a basic component in Next.js that lets users connect their wallet:
"use client";
import { useState } from "react";
import { ethers } from "ethers";
export default function ConnectWallet() {
const [account, setAccount] = useState(null);
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
const provider = new ethers.BrowserProvider(window.ethereum);
const accounts = await provider.send("eth_requestAccounts", []);
setAccount(accounts[0]);
} catch (err) {
console.error("Connection failed", err);
}
} else {
alert("MetaMask not installed");
}
}
return (
<div>
<button onClick={connect}>
{account ? `Connected: ${account}` : "Connect Wallet"}
</button>
</div>
);
}
This component asks MetaMask for permission to connect, then shows the connected wallet address.
Reading Blockchain Data
After connecting, the next step is reading data from a smart contract. Let’s say you have a contract that stores a simple message. Here is how you might fetch it:
"use client";
import { useState, useEffect } from "react";
import { ethers } from "ethers";
const contractAddress = "0xYourContractAddressHere";
const abi = [
"function message() view returns (string)"
];
export default function ReadMessage() {
const [message, setMessage] = useState("");
useEffect(() => {
async function loadMessage() {
if (typeof window.ethereum !== "undefined") {
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
const data = await contract.message();
setMessage(data);
}
}
loadMessage();
}, []);
return (
<div>
<p>Message from contract: {message}</p>
</div>
);
}
This shows how simple it is to display blockchain data on a Next.js page.
Writing to the Blockchain
Reading data is free, but writing requires a transaction. For example, updating that message in the contract:
"use client";
import { useState } from "react";
import { ethers } from "ethers";
const contractAddress = "0xYourContractAddressHere";
const abi = [
"function setMessage(string newMessage)"
];
export default function WriteMessage() {
const [input, setInput] = useState("");
async function updateMessage() {
if (typeof window.ethereum !== "undefined") {
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
const tx = await contract.setMessage(input);
await tx.wait();
alert("Message updated!");
} catch (err) {
console.error(err);
}
}
}
return (
<div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Enter new message"
/>
<button onClick={updateMessage}>Update</button>
</div>
);
}
This example shows how to send transactions from a Next.js app.
Handling Off-Chain Logic
Not every action belongs on the blockchain. Some tasks, like caching results or running data analysis, can be done off-chain. Next.js API routes are a great fit for this. For example:
// pages/api/price.js
export default async function handler(req, res) {
const response = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd");
const data = await response.json();
res.status(200).json({ price: data.ethereum.usd });
}
Now you can call /api/price
from your frontend to get the latest ETH price without exposing your API key or dealing with CORS issues.
Challenges to Keep in Mind
Building Web3 apps with Next.js comes with challenges:
Security: Never expose private keys or sensitive data in the frontend.
User experience: Gas fees and transaction times can frustrate users. Good UI feedback is essential.
Scalability: Blockchain networks can be slow during high demand. Consider using Layer 2 solutions like Polygon or Arbitrum.
The Road Ahead
Web3 is still evolving, but the tools are maturing fast. Next.js brings stability and performance to an ecosystem that sometimes feels chaotic. With features like server-side rendering, flexible APIs, and excellent developer ergonomics, it helps developers focus on building user-friendly dApps instead of wrestling with boilerplate.
As more blockchains scale and mainstream adoption grows, the combination of Next.js and Web3 will become even more powerful. If you are already comfortable with React, this is a great time to explore how to connect your skills to decentralized technologies.
Conclusion
Next.js is not just for startups building marketing sites or e-commerce platforms. It is becoming a bridge between traditional web development and the decentralized future. By combining the strength of Next.js with the openness of Web3, developers can create apps that are fast, secure, and user-centered.
If you are curious about the future of the internet, try building a simple Web3 app with Next.js. Connect a wallet, read from a contract, and send a transaction. That small step could be the start of your journey into decentralized app development.