使用Next.js和Vercel Postgres构建免费的链接缩短器
#javascript #网络开发人员 #react #nextjs

使用Next.js和Vercel Postgres创建一个链接缩短器。学习动态路由,数据库连接和域自定义。

tl; dr

检查演示here

检查源代码here

介绍

链接缩短器已成为共享冗长URL的首选解决方案,尤其是在角色计数很重要的平台上。它们简单,高效且非常方便。在这篇博客文章中,我们正在使用Next.jsVercel Postgres进行简单且免费的链接缩短器的创建。

我们的演示将展示以下功能:

  • 访问SLUG时自动重定向到目标链接
  • 跟踪每个链接的访问次数
  • 显示数据库链接的统计数据

先决条件

除了创建典型的NextJS应用程序的要求外,您还需要一个Vercel帐户。如果您没有一个,则可以注册here

安装

遵循本指南的最简单方法是到degit a Nextjs样板。

npx degit codegino/nextjs-ts-tw-tldr next13-i18n

由于个人喜好,我将使用TailwindCSSTypeScript,但是您可以使用普通的CSS和JavaScript。

安装依赖项

npm i

删除未使用的文件

删除appcomponents文件夹下的所有内容

rm -rf app/* components/*

设置NextJS-第1部分

制作占位符路线解析器

在链接Shortener应用程序中,“ slug”是每个缩短链接的唯一名称。此slug可帮助该应用在单击缩短链接时将用户发送到正确的URL。

我们将使用NextJS的动态路线为我们独特的slug铺路。现在,我们将其保持基础,只需将任何slug重定向到一个页面。

// app/[slug]/route.ts
export const GET = () => {
  return NextResponse.redirect('https://google.com', 302);
};

使用npm run dev运行该应用后,我们可以转到http://localhost:3000/xyz,它应该重定向到Google的主页。

初始部署

首先部署我们的应用程序将简化该过程。 Vercel提供了一种将现有项目连接到数据库的简便方法,该项目将在以后创建。

安装Vercel CLI

首先安装Vercel CLI:

npm i -g vercel

登录到Vercel

接下来,登录到您的Vercel帐户:

vercel login

部署应用程序

最后,部署应用程序:

vercel --prod

有关使用Vercel CLI部署的更多信息,请查看this guide

设置数据库

创建Vercel Postgres数据库

首先,登录您的Vercel帐户,导航到dashboard,然后选择“ Storage”选项卡。然后,单击Create Database按钮。

将出现一个对话框。选择PostgreSQL选项,然后单击Continue

您会看到另一个弹出窗口。如果您同意该条款,请单击Accept。然后,设置您的数据库名称,然后单击Create

创建链接表

当前,Vercel Postgresql没有为各种操作提供内置界面。因此,我们现在使用查询跑步者。

CREATE TABLE links (
    id SERIAL PRIMARY KEY,
    alias VARCHAR(255) NOT NULL UNIQUE,
    target VARCHAR(2048) NOT NULL,
    visit_count INTEGER DEFAULT 0
);

上面的查询将创建一个具有以下列的表:

  • id:每个链接的唯一标识符
  • 别名:将用于创建缩短链接的sl
  • 目标:目标URL
  • visit_count:访问链接的次数

我们可以添加其他跟踪信息,例如源主机,用户代理等。但是,对于此演示,我们将保持简单。

添加一个新链接条目

要测试我们的设置,让我们使用以下查询添加一个新的链接条目:

INSERT INTO links (alias, target) 
VALUES ('nggyu', 'https://www.youtube.com/watch?v=dQw4w9WgXcQ');

我们可以使用Browse选项卡浏览表。

设置NextJS-第2部分

安装Vercel Postgres软件包

首先安装Vercel Postgres软件包:

npm i @vercel/postgres

连接项目

按照以下步骤将您的Vercel项目连接到数据库:

  1. 将您的Vercel项目连接到数据库

  2. 拉动最新环境变量

Vercel简化了从数据库加载环境变量的过程。您可以通过运行以下命令来执行此操作:

vercel env pull .env.development.local
  1. 安装Vercel Postgres软件包
npm install @vercel/postgres
  1. 更新路线处理程序

接下来,用提供的代码替换app/[slug]/route.ts的内容。

// app/[slug]/route.ts
import {NextResponse} from 'next/server';
import {sql} from '@vercel/postgres';

// Exporting an async GET function that takes the params object in the second argument
export const GET = async (_, {params}) => {

  // Making a SQL query to select a link from the links table where the alias matches the provided slug
  // The result is limited to 1 row
  const {rows} =
    await sql`SELECT * FROM links WHERE alias=${params.slug} LIMIT 1`;

  // If no rows are returned, return a response indicating the slug is not in the record
  if (rows.length === 0) {
    return new Response(`<h1>/${params.slug} is not in our record</h1>`, {
      status: 400,
      headers: {
        'content-type': 'text/html',
      },
    });
  }

  // If a row is returned, increment the visit_count for the link with the provided slug
  if (rows[0]) {
    await sql`UPDATE links SET visit_count = visit_count + 1 WHERE alias = ${params.slug}`;
  }

  // Redirect to the target of the first row (the selected link)
  return NextResponse.redirect(rows[0].target, 302);
};

应用程序运行后,访问http://localhost:3000/nggyu应将我们重定向到目标链接。

我们看到了404页,因为我们还没有创建Home/index页面。

设置默认页面(可选)

如果没有提供lug的情况,则该应用程序将尝试解析未定义的根路由。但是,您可以根据需要自定义此行为。对于此演示,我将设置根路由,以显示数据库中所有链接的基本统计信息。

创建布局组件

// app/layout.ts
import '../styles/tailwind.css';

export const metadata = {
  title: 'Next Link Shortener',
  description: 'Generated by Next.js',
};

export default function RootLayout({children}: {children: React.ReactNode}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

创建主页

此页面将以表格式显示数据库中所有链接的统计信息。

// app/page.ts
import React from 'react';
import {sql} from '@vercel/postgres';

const Page = async () => {
  const links = await getData();

  return (
    <div className="min-h-screen bg-gray-100 flex flex-col items-center pt-8">
      <h1 className="text-2xl font-bold mb-5 text-gray-900">Links stats</h1>
      <div className="flex flex-col items-center overflow-hidden">
        <table className="min-w-full divide-y divide-gray-200">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-6 py-3 text-left font-medium">Alias</th>
              <th className="px-6 py-3 text-left font-medium">Target</th>
              <th className="px-6 py-3 text-left font-medium">Visit Count</th>
            </tr>
          </thead>
          <tbody className="bg-white divide-y divide-gray-200">
            {links.map((link, index) => (
              <tr key={index}>
                <td className="px-6 py-4 whitespace-nowrap">{link.alias}</td>
                <td className="px-6 py-4 whitespace-nowrap">{link.target}</td>
                <td className="px-6 py-4 whitespace-nowrap">
                  {link.visit_count}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

const getData = async () => {
  const {rows} = await sql`SELECT * FROM links`;

  return rows;
};

export default Page;

运行应用程序后,每次访问别名都应增加访问数量。

自定义域

如果不自定义我们的域,我们可能最终会获得更长的链接,从而破坏了链接缩短器的目的。例如,Vercel为此演示提供的默认域是https://demo-nextjs-link-shortener.vercel.app/nggyu

与Vercel

Vercel允许我们修改域。这是过程:

  1. 导航到Settings选项卡
  2. 选择Domains
  3. 选择要修改的域
  4. 击中Edit
  5. 输入您要使用的子域,然后单击Save

与DNS提供商

上一个选项很棒,但是域中有Vercel品牌。如果要删除它,可以使用自己的域。

记住,这不是免费的,因为您需要购买域。我从NameCheap

得到了我

设置它:

  1. 如果您使用的是namecheap,请转到仪表板上的Advanced DNS选项卡。 >如果您使用的是其他提供商,则可以Google如何在<your provider>中添加CNAME Record
  2. 创建新记录
  3. 要将所有流量引导到Vercel,我添加了带有主机@和Value 76.76.21.21A Record
  4. 接下来,我添加了一个带有主机links和value cname.vercel-dns.comCNAME Record

在Vercel中添加自定义域:

  1. 转到Settings选项卡
  2. 单击Domains
  3. 输入要在文本字段中添加的域
  4. 单击Add

可能会询问您是否要将现有流量重定向到我建议这样做的新域。

设置后,您应该拥有一个可以与世界共享的功能齐全的链接shortener应用程序。

结论

总而言之,我们探索了如何使用next.js和vercel Postgres,设置动态路由,连接到数据库并跟踪链接访问来构建链接Shortener。我们还深入研究了使用Vercel和DNS提供商自定义域,展示了我们设置的灵活性。请记住,虽然此演示是基本的,但它为扩展的无尽可能性打开了大门。愉快的编码!