Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ keywords:

# Building a Frontend App

Building on the `Counter` contract you deployed in [Cadence Environment Setup] and [Smart Contract Interaction], this tutorial shows you how to create a simple Next.js frontend that interacts with the `Counter` smart contract deployed on your local Flow emulator. Instead of using FCL directly, you'll leverage [**@onflow/react-sdk**] to simplify authentication, querying, transactions, and to display real-time transaction status updates using convenient React hooks.
This tutorial builds on the `Counter` contract you deployed in [Cadence Environment Setup] and [Smart Contract Interaction]. It shows you how to create a simple `Next.js` frontend that interacts with the `Counter` smart contract deployed on your local Flow emulator. Instead of using FCL directly, you'll leverage [**@onflow/react-sdk**] to simplify authentication, querying, transactions, and to display real-time transaction status updates using convenient React hooks.

## Objectives

After finishing this guide, you will be able to:
After you complete this tutorial, you will be able to:

- Wrap your Next.js app with a Flow provider using [**@onflow/react-sdk**].
- Wrap your `Next.js` app with a Flow provider using [**@onflow/react-sdk**].
- Read data from a Cadence smart contract (`Counter`) using kit's query hook.
- Send a transaction to update the smart contract's state using kit's mutation hook.
- Monitor a transaction's status in real time using kit's transaction hook.
Expand All @@ -40,7 +40,7 @@ After finishing this guide, you will be able to:
- [Flow CLI] installed.
- Node.js and npm installed.

## Setting Up the Next.js App
## Set Up the Next.js app

Follow these steps to set up your Next.js project and integrate [**@onflow/react-sdk**].

Expand All @@ -50,7 +50,7 @@ You can visit this [React-sdk Demo] to see how the hooks and components are used

:::

### Step 1: Create a New Next.js App
### Step 1: Create a new Next.js app

Run the following command in your project directory:

Expand All @@ -66,7 +66,7 @@ During setup, choose the following options:

This command creates a new Next.js project named `kit-app-quickstart` inside your current directory. We're generating the frontend in a subdirectory so we can next move it into our existing project structure from the previous steps (you can't create an app in a non-empty directory).

### Step 2: Move the Next.js App Up a Directory
### Step 2: Move the Next.js app Up a directory

Move the contents of the `kit-app-quickstart` directory into your project root. You can use the gui in your editor, or the console.

Expand All @@ -92,7 +92,11 @@ Move-Item -Path .\kit-app-quickstart\.* -Destination . -Force
Remove-Item -Recurse -Force .\kit-app-quickstart
```

**Note:** When moving hidden files (those beginning with a dot) like `.gitignore`, be cautious not to overwrite any important files.
:::tip

When moving hidden files (those beginning with a dot) like `.gitignore`, be cautious not to overwrite any important files.

:::

### Step 3: Install @onflow/react-sdk

Expand All @@ -104,11 +108,11 @@ npm install @onflow/react-sdk

This library wraps FCL internally and exposes a set of hooks for authentication, querying, sending transactions, and tracking transaction status.

## Configuring the Local Flow Emulator and Dev Wallet
## Configure the local Flow Emulator and Dev Wallet

:::warning

You should already have the Flow emulator running from the local development step. If it's not running, you can start it again — but note that restarting the emulator will clear all blockchain state, including any contracts deployed in [Step 2: Local Development].
You should already have the Flow emulator running from the local development step. If it's not running, you can start it again — but when you restart the emulator, it will clear all blockchain state, which includes any contracts deployed in [Step 2: Local Development].

:::

Expand All @@ -132,9 +136,9 @@ flow dev-wallet

This will start the [Dev Wallet] on `http://localhost:8701`, which you'll use for authentication during development.

## Wrapping Your App with FlowProvider
## Wrap Your app with FlowProvider

[**@onflow/react-sdk**] provides a `FlowProvider` component that sets up the Flow Client Library configuration. In Next.js using the App Router, add or update your `src/app/layout.tsx` as follows:
[**@onflow/react-sdk**] provides a `FlowProvider` component that sets up the Flow Client Library configuration. In `Next.js` using the App Router, add or update your `src/app/layout.tsx` as follows:

```tsx
'use client';
Expand Down Expand Up @@ -170,11 +174,11 @@ This configuration initializes the kit with your local emulator settings and map

For more information on Discovery configurations, refer to the [Wallet Discovery Guide].

## Interacting With the Chain
## Interact With the chain

Now that we've set our provider, lets start interacting with the chain.

### Querying the Chain
### Query the chain

First, use the kit's [`useFlowQuery`] hook to read the current counter value from the blockchain.

Expand Down Expand Up @@ -208,7 +212,7 @@ This script fetches the counter value, formats it via the `NumberFormatter`, and

:::

### Sending a Transaction
### Send a transaction

Next, use the kit's [`useFlowMutate`] hook to send a transaction that increments the counter.

Expand Down Expand Up @@ -244,9 +248,9 @@ const handleIncrement = () => {

#### Explanation

This sends a Cadence transaction to the blockchain using the `mutate` function. The transaction imports the `Counter` contract and calls its `increment` function. Authorization is handled automatically by the connected wallet during the `prepare` phase. Once submitted, the returned `txId` can be used to track the transaction's status in real time.
This sends a Cadence transaction to the blockchain using the `mutate` function. The transaction imports the `Counter` contract and calls its `increment` function. The connected wallet handles authorization automatically during the `prepare` phase. After it's submitted, you cna use the returned `txId` to track the transaction's status in real time.

### Subscribing to Transaction Status
### Subscribe to transaction status

Use the kit's [`useFlowTransactionStatus`] hook to monitor and display the transaction status in real time.

Expand Down Expand Up @@ -275,19 +279,19 @@ useEffect(() => {
- `2`: **Finalized** – The transaction has been included in a block, but not yet executed.
- `3`: **Executed** – The transaction code has run successfully, but the result has not yet been sealed.
- `4`: **Sealed** – The transaction is fully complete, included in a block, and now immutable onchain.
- We recommend calling `refetch()` when the status reaches **3 (Executed)** to update your UI more quickly after the transaction runs, rather than waiting for sealing.
- We recommend that you call `refetch()` when the status reaches **3 (Executed)** to update your UI more quickly after the transaction runs, rather than waiting for sealing.
- The `statusString` property gives a human-readable version of the current status you can display in the UI.

#### Why `Executed` is Recommended for UI Updates:
#### Why we recommend `Executed` for UI Updates:

Waiting for `Sealed` provides full onchain confirmation but can introduce a delay — especially in local or test environments. Since most transactions (like incrementing a counter) don't require strong finality guarantees, you can typically refetch data once the transaction reaches `Executed` for a faster, more responsive user experience.

However:

- If you're dealing with critical state changes (e.g., token transfers or contract deployments), prefer waiting for `Sealed`.
- If you're dealing with critical state changes (for example, token transfers or contract deployments), prefer waiting for `Sealed`.
- For non-critical UI updates, `Executed` is usually safe and significantly improves perceived performance.

### Integrating Authentication and Building the Complete UI
### Integrate authentication and build the complete UI

Finally, integrate the query, mutation, and transaction status hooks with authentication using `useFlowCurrentUser`. Combine all parts to build the complete page.

Expand Down Expand Up @@ -413,7 +417,7 @@ In this tutorial, we inlined Cadence code for simplicity. For real projects, we

:::

## Running the App
## Run the app

Start your development server:

Expand Down Expand Up @@ -442,9 +446,9 @@ Then visit [http://localhost:3000](http://localhost:3000) in your browser. You s
- Once logged in, your account address appears with options to **Log Out** and **Increment Count**.
- When you click **Increment Count**, the transaction is sent; its status updates are displayed in real time below the action buttons, and once the transaction is sealed, the updated count is automatically fetched.

## Wrapping Up
## Conclusion

By following these steps, you've built a simple Next.js dApp that interacts with a Flow smart contract using [**@onflow/react-sdk**]. In this guide you learned how to:
By following these steps, you've built a simple `Next.js` dApp that interacts with a Flow smart contract using [**@onflow/react-sdk**]. In this guide you learned how to:

- Wrap your application in a `FlowProvider` to configure blockchain connectivity.
- Use kit hooks such as `useFlowQuery`, `useFlowMutate`, `useFlowTransactionStatus`, and `useFlowCurrentUser` to manage authentication, query onchain data, submit transactions, and monitor their status.
Expand Down
Loading