1. Bootstrapping Next.js frontend project
NextJS App Router (Typescript) + TailwindCSS + Shadcn UI
Next.js Pages/App Router is a full-stack React framework. The framework is flexible and helps you build large or small React applications. To start creating a new Next.js project, run the following command in the terminal:
npx create-next-app@latest my-app --typescript --tailwind --eslint
You will see the following prompts in the terminal:
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*
For each prompt, you will choose the following options:
What is your project named? my-app
Would you like to use TypeScript? Yes # Typescript is currently the top choice
Would you like to use ESLint? Yes # ESLint to lint your code
Would you like to use Tailwind CSS? Yes # Tailwind CSS for writing interfaces quickly
Would you like to use `src/` directory? No # Do not use src directory because it is not necessary
Would you like to use App Router? (recommended) Yes # Use App router to take advantage of the latest nextjs features
Would you like to customize the default import alias (@/*)? No # No, use default
Visit Next.JS Docs here if you have problems: https://nextjs.org/docs
cd
into your directory (my-app
or whichever name you chose) and run the following command to install Shadcn UI
npx shadcn-ui@latest init
You will see the following prompts to set up components.json
:
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Do you want to use CSS variables for colors? › no / yes
You can choose according to your preferences, but for this bootcamp you will choose:
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Do you want to use CSS variables for colors? › yes
Learn more with ShadcnUI's tutorial: https://ui.shadcn.com/docs/installation/next
A special feature of Shadcn UI is that the library will create a components
folder directly in the project as below:
.
└── components
├── ui
│ ├── button.tsx
│ ├── input.tsx
│ ├── card.tsx
│ └── form.tsx
└── authentication-menu.tsx
You will use the components in the ui
folder to build your own custom components
. For example above, you use 4 components button.tsx
, input.tsx
, card.tsx
and form.tsx
to create a custom component authentication-menu.tsx
.
2. Create project on WalletConnect
Visit https://cloud.walletconnect.com/sign-in.
Create an account and follow the instructions on the Dashboard to set up a Project ID.
WalletConnect will use your Project ID to track connection requests.
Wagmi + Rainbowkit + Tanstack React Query
Wagmi is a React Hook library for building interfaces more quickly. In particular, Wagmi also provides convenient React Hooks to be able to manage the entire lifecycle of a transaction, basically from connecting the wallet, to initiating the transaction, to waiting for results from the node to return and process. error handling or successful transaction status. Managing the entire lifecycle of a transaction well will help increase user experience, helping them understand their own activities.
You will install the wagmi library in common with Rainbowkit
npm install @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query
Next, you create the providers.tsx
file in the app
directory
'use client';
import * as React from 'react';
import {
RainbowKitProvider,
getDefaultWallets,
getDefaultConfig,
} from '@rainbow-me/rainbowkit';
import {
trustWallet,
ledgerWallet,
} from '@rainbow-me/rainbowkit/wallets';
import {
klaytn, // import klaytn mainnet
klaytnBaobab, // import klaytn testnet
} from 'wagmi/chains';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { WagmiProvider, http } from 'wagmi';
// import according to docs
const { wallets } = getDefaultWallets();
// initialize and destructure wallets object
const config = getDefaultConfig({
appName: 'MY_APP', // Name your app
projectId: "WALLETCONNECT_PROJECT_ID", // Enter your WalletConnect Project ID here
wallets: [
...wallets,
{
groupName: 'Other',
wallets: [trustWallet, ledgerWallet],
},
],
chains: [
klaytn,
klaytnBaobab
],
transports: {
[klaytn.id]: http('https://rpc.ankr.com/klaytn'), // Select RPC provider Ankr instead of the default
[klaytnBaobab.id]: http('https://rpc.ankr.com/klaytn_testnet'), // Select RPC provider Ankr instead of the default
},
ssr: true, // Because it is Nextjs's App router, you need to declare ssr as true
});
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
{children}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
Next, add this code to the next.config.mjs
file:
/** @type {import('next').NextConfig} */
const nextConfig = {
...
reactStrictMode: true,
webpack: config => {
config.externals.push('pino-pretty', 'lokijs', 'encoding');
return config;
},
};
export default nextConfig;
Next, wrap <Providers>
around children
in your layout.tsx
file to this:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import '@rainbow-me/rainbowkit/styles.css';
import { Providers } from './providers';
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Klaytn DApp Bootcamp Frontends",
description: "Interactive frontend for Klaytn DApp bootcamp contracts",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<Providers>
{children}
</Providers>
</body>
</html>
);
}
3. Connect Wallet Button
You can then import <ConnectButton />
into your app
import { ConnectButton } from '@rainbow-me/rainbowkit';
export default function Home() {
return (
<div className="flex flex-col gap-8 items-center justify-center py-12 px-4 p-48:lg">
<ConnectButton />
</div>
);
}
Visit Rainbowkit docs to learn more about settings: https://www.rainbowkit.com/docs/installation
Link to full source code on Github