首页 >web前端 >js教程 >在 Fleek 上使用 Next.js 构建 WebRL 缩短器

在 Fleek 上使用 Next.js 构建 WebRL 缩短器

DDD
DDD原创
2024-12-18 21:19:09955浏览

Building a WebRL shortener with Next.js on Fleek

传统的 URL 缩短程序依赖集中式服务,这使得它们容易受到审查、数据泄露和单点故障的影响。去中心化、Web3 驱动的 URL 缩短器通过在区块链上存储链接映射来解决这些问题,确保不变性、透明度和抗审查性。
在本指南中,我们将使用 Next.js、以太坊智能合约和 Fleek 的边缘优化托管构建完全去中心化的 URL 缩短服务。最后,您将拥有一个简化的 Next.js 应用程序,使用户能够无缝地缩短、存储和解析 URL。


为什么选择 Web3 URL 缩短工具?

主要优点:

  • 去中心化:将缩短的 URL 存储在区块链上,以实现弹性和不变性。
  • 审查制度的抵抗:没有任何一个权威机构可以任意删除链接。
  • 透明度:用户可以验证缩短的 URL 是否映射到正确的目的地。

先决条件

确保您拥有:

  1. 前端技能:熟悉 React 或 Next.js。
  2. Node.js 和 npm:安装在您的系统上。
  3. Fleek 帐户和 CLI:在 Fleek 注册并安装 Fleek CLI。
  4. Reown 项目:在 Reown 创建一个项目。
  5. 测试加密钱包:合约交互所需。
  6. Web3 基础知识:了解智能合约和区块链基础知识。

第 1 步:项目设置

  • 初始化 Next.js 项目:
npx create-next-app@latest
  • 回答以下提示:
Project name? web3-url-shortener
Use TypeScript? No
Use ESLint? No
Use Tailwind CSS? Yes
Use `src/` directory? Yes
Use App Router? No
Use Turbopack? No
Customize import alias? No
  • 安装依赖项:
npm install wagmi ethers @tanstack/react-query @rainbow-me/rainbowkit

# fleek-next adapter
npm install @fleek-platform/next
  • 确保 @fleek-platform/next 是 v2 或更高版本。
  • 登录 Fleek:
fleek login
  • 按照屏幕上的说明进行操作。
  • 创建目录: 在 src/ 中,创建目录 lib 和 abi。
  • 运行开发服务器:
npm run dev

智能合约设置

  • 合约源码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract UrlShortener {
    // Maps a short code (e.g. "abc123") to a full URL
    mapping(string => string) private shortToLong;

    event URLShortened(string indexed shortCode, string longUrl);

    /**
     * @notice Create a shortened URL by mapping a short code to a long URL.
     * @param shortCode The short code (unique identifier)
     * @param longUrl The long URL to map to
     */
    function setURL(string calldata shortCode, string calldata longUrl) external {
        require(bytes(shortCode).length > 0, "Short code cannot be empty");
        require(bytes(longUrl).length > 0, "Long URL cannot be empty");
        // In a production scenario, you'd probably want some uniqueness checks,
        // or handle collisions differently. For now we allow overwriting.

        shortToLong[shortCode] = longUrl;
        emit URLShortened(shortCode, longUrl);
    }

    /**
     * @notice Retrieve the long URL for a given short code.
     * @param shortCode The short code to look up
     * @return longUrl The long URL that the short code points to
     */
    function getURL(string calldata shortCode) external view returns (string memory) {
        return shortToLong[shortCode];
    }
}

上述 UrlShortener 智能合约允许用户创建和管理缩短的 URL。它将唯一的短代码映射到长 URL,从而实现高效的 URL 存储和检索。用户可以使用 setURL 函数设置映射并使用 getURL 检索原始 URL。该合约包括基本验证,并在新 URL 缩短时发出事件。我已经部署了我的合约,地址是:0x2729D62B3cde6fd2263dF5e3c6509F87C6C05892

  • 链: Arbitrum Sepolia 测试网
  • ABI 源代码: URLShortener
  • RPC URL: 从 Alchemy 或其他提供商获取。
  • Arbitrum Sepolia 水龙头: 水龙头

.env 设置:

在项目根目录创建一个.env:

npx create-next-app@latest

配置ABI和合约

  • 添加 ABI:

使用以下命令创建 src/abi/URLShortener.json:

Project name? web3-url-shortener
Use TypeScript? No
Use ESLint? No
Use Tailwind CSS? Yes
Use `src/` directory? Yes
Use App Router? No
Use Turbopack? No
Customize import alias? No
  • 合约配置文件:

在 src/lib/contract.js 中:

npm install wagmi ethers @tanstack/react-query @rainbow-me/rainbowkit

# fleek-next adapter
npm install @fleek-platform/next
  • Wagmi 配置:
fleek login

将 {{REOWN-PROJECT-ID}} 和 {{REOWN-APP-NAME}} 替换为您在 Reown 中的详细信息。


第 2 步:构建前端

提供商设置:

下面,我将展示如何在 Next.js 应用程序中正确设置 web3 提供程序,以正确处理客户端渲染。

关键是将提供程序分为两部分,以安全地处理必须仅在浏览器中运行的 web3 功能。

创建 src/lib/providers.js:

npm run dev

创建 src/lib/Web3Providers.jsx:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract UrlShortener {
    // Maps a short code (e.g. "abc123") to a full URL
    mapping(string => string) private shortToLong;

    event URLShortened(string indexed shortCode, string longUrl);

    /**
     * @notice Create a shortened URL by mapping a short code to a long URL.
     * @param shortCode The short code (unique identifier)
     * @param longUrl The long URL to map to
     */
    function setURL(string calldata shortCode, string calldata longUrl) external {
        require(bytes(shortCode).length > 0, "Short code cannot be empty");
        require(bytes(longUrl).length > 0, "Long URL cannot be empty");
        // In a production scenario, you'd probably want some uniqueness checks,
        // or handle collisions differently. For now we allow overwriting.

        shortToLong[shortCode] = longUrl;
        emit URLShortened(shortCode, longUrl);
    }

    /**
     * @notice Retrieve the long URL for a given short code.
     * @param shortCode The short code to look up
     * @return longUrl The long URL that the short code points to
     */
    function getURL(string calldata shortCode) external view returns (string memory) {
        return shortToLong[shortCode];
    }
}

修改_app.js:

在pages/_app.js中:

NEXT_PUBLIC_CONTRACT_ADDRESS=0x2729D62B3cde6fd2263dF5e3c6509F87C6C05892
NEXT_PUBLIC_RPC_URL={{YOUR-ARBITRUM-SEPOLIA-RPC-URL}}

主用户界面(pages/index.js):

此页面处理连接钱包、输入长 URL 和短代码以及写入区块链。我们将进行与上面类似的拆分。造成这种分裂的主要原因:

  • Web3代码需要window.ethereum,它只存在于浏览器中
  • ssr: false 阻止服务器端渲染 web3 代码
  • 主页组件仍然可以通过服务器渲染以获得更好的性能
  • 防止“窗口未定义”错误
  • 将仅浏览器的代码与服务器兼容的代码完全分开

在pages/index.js:

{
  "abi": [
    {
      "anonymous": false,
      "inputs": [
        { "indexed": true, "internalType": "string", "name": "shortCode", "type": "string" },
        { "indexed": false, "internalType": "string", "name": "longUrl", "type": "string" }
      ],
      "name": "URLShortened",
      "type": "event"
    },
    {
      "inputs": [{ "internalType": "string", "name": "shortCode", "type": "string" }],
      "name": "getURL",
      "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        { "internalType": "string", "name": "shortCode", "type": "string" },
        { "internalType": "string", "name": "longUrl", "type": "string" }
      ],
      "name": "setURL",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]
}

创建 src/lib/URLShortenerApp.jsx:

import { ethers } from "ethers";
import urlShortenerJson from "../abi/URLShortener.json";

export function getSignerContract(signer) {
  if (!signer) {
    console.error("No signer provided to getSignerContract");
    throw new Error("No signer available");
  }

  const address = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS;
  if (!address) {
    throw new Error("Contract address not configured");
  }

  return new ethers.Contract(address, urlShortenerJson.abi, signer);
}

最后一件事是确保您的 tailwind.config.js 与以下内容匹配:

import { http} from "wagmi";
import { arbitrumSepolia } from "wagmi/chains";
import { getDefaultConfig } from "@rainbow-me/rainbowkit";

const projectId = {{REOWN-PROJECT-ID}};

export const config = getDefaultConfig({
  appName: {{REOWN-APP-NAME}},
  projectId: projectId,
  chains: [arbitrumSepolia],
  transports: {
    [arbitrumSepolia.id]: http(),
  },
  ssr: false,
});

第 3 步:部署到 Fleek

  • 调整边缘运行时:

对于服务器端和动态路由,请确保您有:在文件中导出 const runtime = 'edge'。

  • 使用 Fleek 构建:

1.构建应用程序:

"use client";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";

const Web3Providers = dynamic(() => import("./Web3Providers"), {
  ssr: false,
});

export default function Providers({ children }) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return <>{children}</>;
  }

  return <Web3Providers>{children}</Web3Providers>;
}

这会生成一个 .fleek 目录。

2.创建 Fleek 函数:

// Web3Providers.jsx
"use client";

import { WagmiProvider } from "wagmi";
import "@rainbow-me/rainbowkit/styles.css";
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { config } from "../lib/wagmi";

export default function Web3Providers({ children }) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        refetchOnWindowFocus: false,
      },
    },
  });

  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider
          theme={darkTheme({
            accentColor: "#0E76FD",
            accentColorForeground: "white",
            borderRadius: "large",
            fontStack: "system",
            overlayBlur: "small",
          })}
        >
          {children}
        </RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
}

3.为您的函数命名(例如,web3-url-shortener-next-js)。

4.部署到 Fleek:

import "../styles/globals.css";
import "@rainbow-me/rainbowkit/styles.css";

import Providers from "../lib/providers";

function App({ Component, pageProps }) {
  return (
    <Providers>
      <Component {...pageProps} />
    </Providers>
  );
}

export default App;

成功部署后,Fleek 将提供一个 URL 来访问您的应用程序。


结论

您已经成功构建并部署了一个去中心化的 URL 缩短器:

  • 在链上存储映射。
  • 实现无需信任、抗审查的链接缩短。
  • 使用 Fleek 进行边缘部署和简化的 Web3 体验。

这个基础可以扩展或集成到更大的 Next.js 应用程序中。尝试自定义 UI、跟踪分析或集成其他智能合约来增强您的 Web3 URL 缩短器。在此处查看最终结果应如下所示:https://shortener.on-fleek.app/

您可以前往Github仓库查看完整代码:https://github.com/tobySolutions/shortener

本文最初发布于 Fleek 博客

以上是在 Fleek 上使用 Next.js 构建 WebRL 缩短器的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn