使用Nextjs快速开发全栈导航网站

这篇具有很好参考价值的文章主要介绍了使用Nextjs快速开发全栈导航网站。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

随着ChatGPT的火热,国外很多开发者快速响应,应用于不同场景的AI应用井喷式的爆发,并且基本集中在web领域应用,而在快速开发的背后,我们可以看到,开发者大多选择Next.js或者Nuxt.js全栈框架来开发,以快速验证自己的产品。这种选型的背后,我觉得主要原因有:

  • SEO的重要性

    国外更加注重SEO的重要性,国内搜索引擎大多是靠花钱买搜索流量,包括小程序、App这类对SEO的需求并不大

  • Edge Function的兴起

    Serverless使得前端开发能快速开发全栈应用,方便的托管自己后端服务,而不用过多关注部署,然而他的缺点是,多数Serverless都是采用容器化的方案,因此冷启动时间长,如果在自己的云函数转发请求OpenAI接口,可能会发生请求时间很长的情况。如今, Vercel、CloudFlare、Supabase等厂商都有了Edge Function的能力,使得函数可以在一些距离用户更近的边缘节点运行,为了更快的冷启动时间来快速响应用户,这种方案一般也加了部分限制,但是依旧得到很多开发者的青睐

  • 云服务厂商的多样性

    云服务厂商提供了很多基础服务,当把项目托管给Vercel等服务时,可以与Github集成进行持续部署,同时还会分配一个域名。很多其他厂商也提供了很多的免费后端存储服务,例如:

    • Upsatsh提供的Redis
    • Supabase提供的PostgreSQL
    • PlantScale提供的MySQL
    • Clerk提供的用户认证和用户管理

以上这些厂商的免费计划对于个人开发完全够用,当然也可以根据产品规模使用付费计划

而本文旨在尝试开发一个简单的导航页面,满足自己的收集癖好,用于解放自己的收藏夹,来学习Next.js开发,体验Next.js带来的开发全栈应用的便捷性,你可以打开页面体验,也可以在本项目开源地址查看完整代码。

初始化项目

随着以tailwindcssunocss这种原子化CSS方案的出现,基于此衍生出来的UI组件库也很多,比如Radix、daisyUI、flowbite, 其中的RadixUI组件库相当注重网页的可访问性,组件都遵循WAI-ARIA标准,这使得开发者构建可访问的UI界面变得更加容易,而因为他专注于可访问性、属于Headless UI也就是无具体样式类名代码,因此shadcn作者开发了shadcn/ui组件库,在此RadixUI组件库基础上赋予了简洁美观的样式,得到了很多开发者的青睐, 也非常推荐大家体验下。

这里直接选择克隆该作者的Nextjs模版初始化项目

git clone https://github.com/shadcn/next-template

该项目使用了Next.js最新的app router版本,并且已经集成了tailwindcssshadcn/ui组件库。这里选择做导航网站也是因为它足够简单,关键样式是针对侧边栏,因为tailwindcss是移动端优先,所以这里设置默认隐藏,当屏幕宽度大于sm时展示。

<div className="fixed z-20 hidden min-h-screen sm:block">
	...
</div>

而对于列表区域,采用grid布局,默认移动端优先一列,根据屏幕大小展示2列或者3

<div className="grid grid-cols-1 gap-3 md:grid-cols-2 md:gap-6 lg:grid-cols-3">
   ...
</div>

其他的样式可以借鉴一下别人的网站设计简单美化下,对于不太熟悉css并且缺乏审美的我花了不少的时间在调整,总觉得网站不够美观,但是又不知道该如何美化。

数据库集成

定义模型

数据库集成这里我选择了Prisma,类似的比较热门的还有Drizzle,针对Prisma的具体概念、使用和它的优点,可以参考我整理记录的笔记。执行

npx prisma init

会创建prisma/schema.prisma文件,创建模型如下

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model Category {
  id          String   @id @default(cuid())
  icon        String
  title       String
  description String
  rank        Int?
  createdAt   DateTime @default(now()) @map(name: "created_at")
  updatedAt   DateTime @default(now()) @map(name: "updated_at")
  links       Link[]

  @@map(name: "category")
}

model Link {
  id          String   @id @default(cuid())
  icon        String
  url         String
  title       String
  description String
  rank        Int?
  public      Boolean  @default(true)
  status      Int      @default(1) @db.TinyInt
  createdAt   DateTime @default(now()) @map(name: "created_at")
  updatedAt   DateTime @default(now()) @map(name: "updated_at")
  cid         String
  catagory    Category @relation(fields: [cid], references: [id])

  @@map(name: "link")
}

其中DATABASE_URL为远程数据库地址,这里我使用的是PlantScaleMySQL。当然你也可以使用SupabasePostgreSQL或者其他数据库,创建.env文件,填入服务地址

DATABASE_URL='mysql://user:password@aws.connect.psdb.cloud/dev?sslaccept=strict'

可以在这个可视化Prisma模型网站看到关系图如下, 分别表示类别实例和网站链接实例

表同步

然后执行命令将本地模型同步到数据库表

npx prisma db push

然后可能会遇到下面报错

查阅后发现官网在文档中有说明,PlanetScale的MySQL数据库不支持外键,需要特殊的指定relationMode

datasource db {
  provider     = "mysql"
  url          = env("DATABASE_URL")
  relationMode = "prisma"
}

relationMode默认值是foreignKeys,当使用PlanetScale数据库的MySQL连接器时,应启用此选项, 在Prisma Client中模拟关系。再次执行db push指令,将模型同步到数据库

插入和查询数据

然后执行

npx prisma studio

打开表编辑器添加自己的数据

执行命令生成PrismaClient实例

pnpm install @prisma/client
npx prisma generate

然后就可以通过关联关系一次性查询出数据

import prisma from '@/lib/db';
import type { Prisma } from '@prisma/client';

export default async function getNavLinks() {
  const res = await prisma.category.findMany({
    orderBy: [
      {
        rank: 'asc',
      }
    ],
    include: {
      links: {
        orderBy: {
          rank: 'asc',
        },
        where: {
          public: true,
          status: 1,
        },
      },
    },
  });
  return res;
}

export type CategoryWithLinks = Prisma.PromiseReturnType<typeof getNavLinks>

用户认证

Next.js中集成用户认证非常简单,可以直接使用NextAuth

NextAuth

NextAuth是一个为Next.js应用程序提供的开源身份验证解决方案。默认情况下,NextAuth使用JSON Web Tokens(JWT)保存用户会话。NextAuth支持流行的登录服务,如GoogleFacebookAuth0Apple、电子邮件以及OAuth 1.02.0服务等等,是一种灵活可配置的身份验证解决方案。

首先安装所需依赖

pnpm install next-auth @next-auth/prisma-adapter

按照官方文档指引添加用户相关模型

model Account {
  id                 String  @id @default(cuid())
  userId             String
  type               String
  provider           String
  providerAccountId  String
  refresh_token      String?  @db.Text
  access_token       String?  @db.Text
  expires_at         Int?
  token_type         String?
  scope              String?
  id_token           String?  @db.Text
  session_state      String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime

  @@unique([identifier, token])
}

GitHub

获取Github客户端ID,参考文档,包含以下步骤:

  1. 打开GitHub应用程序页面,点击创建Github应用。

  2. 输入名称、主页、以及授权后的回调地址,这里开发环境时填localhost:3000,上线时切换成自己的线上域名即可。

  3. 点击”生成”并保存Client IDClient Secret

Google

参考NextAuth文档指引,在Google开发者网站注册应用并选择api服务

应用类型选择Web应用,类似Github填上可信任的域名和回调地址确认

创建 API 路由

首先在.env文件中添加上面保存的认证相关密钥,其中NEXTAUTH_SECRET是用户生成JWT的密钥

# google登录
GOOGLE_CLIENT_ID="GOOGLE_CLIENT_ID"
GOOGLE_CLIENT_SECRET="GOOGLE_CLIENT_SECRET"

# github登录
GITHUB_CLIENT_ID="GITHUB_CLIENT_ID"
GITHUB_CLIENT_SECRET="GITHUB_CLIENT_SECRET"

NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="webnav"

可以看到上面的API回调地址分别是/api/auth/github/api/auth/google, 创建app/api/auth/[…nextauth]/route.ts 文件,并添加以下代码片段:

import NextAuth, { type NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import GitHubProvider from "next-auth/providers/github";
import CredentialsProvider from "next-auth/providers/credentials";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
import { compare } from "bcrypt";

const prisma = new PrismaClient();

export const authOptions: NextAuthOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        const { email, password } = credentials ?? {}
        if (!email || !password) {
          throw new Error("Missing username or password");
        }
        const user = await prisma.user.findUnique({
          where: {
            email: credentials?.email,
          },
        });
        // if user doesn't exist or password doesn't match
        if (!user || !(await compare(password, user.password!))) {
          throw new Error("Invalid username or password");
        }
        return user;
      },
    })
  ],
  session: {
    strategy: "jwt",
  },
  debug: process.env.NODE_ENV !== "production",
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };

其中,GitHubProvider用户Github登录,GoogleProvider用于Google登录,CredentialsProvider用于自定义登录,这里会检查邮箱密码, 匹配上了就返回用户信息。

同时还需要创建注册登录页面,创建app/login/page.tsx文件和app/register/page.tsx 文件,页面直接复制的taxonomy 页面样式,自己加上google登录按钮,效果如图

页面上通过

import { signIn, signOut } from "next-auth/react"

signIn方法允许使用GoogleGitHub帐户进行登录。 signOut允许注销用户会话, 具体使用可以参考官方文档这部分

部署

[Vercel](https://vercel.com/)中直接导入项目,修改构建命令为

npx prisma generate && next build

build之前先生成PrismaClient类型,不然编译时会因为类型报错而失败,同时添加.env中所需要的环境变量

同时因为我们的数据源在数据库,而Nextjs默认是构建时生成页面的也就是SSG模式,在数据库有数据更新时我们需要更新页面内容,因此我们需要使用它的增量静态生成ISR(Incremental Static Regeneration)模式,参考官方文档,在page.tsx中添加导出,这里对更新时效性要求不高所以设置为1

export const revalidate = 24 * 60 * 60;

从构建日志中可以看到已经生效了

部署成功后绑定自定义域名就完结撒花了。

总结

本文以简单的导航网站举例,结合Next.jsPrismaNextAuthshadcn/ui 来学习如何构建全栈应用,你可以打开页面体验,也可以在本项目开源地址查看完整代码,最后码字不易,如果你都看到这了,麻烦star一波,感谢。文章来源地址https://www.toymoban.com/news/detail-486150.html

到了这里,关于使用Nextjs快速开发全栈导航网站的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【全栈开发】使用NestJS、Angular和Prisma 打造全栈Typescript开发

    在开发Angular应用程序时,我非常喜欢Typescript。使用NestJS,您可以以与Angular非常相似的方式编写后端。 我偶然发现了这个库,发现它非常有趣,所以我想设置一个简单的测试项目。一般来说,我主要使用SQL数据库,因此我也将尝试Prisma将我们的数据存储在PostgreSQL中,并在前

    2024年02月04日
    浏览(41)
  • 【vue】 网站动态背景 | vanta.js的使用

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 vanta.js可以为网站设置炫酷的动态背景 比如在网站登陆的首页 示例:vanta.js可以为网站设置炫酷的动态背景 比如在网站登陆的首页。 首先我的测试项目是vue2版本 ,关于React和Angular框架自行查看npm官网

    2024年02月08日
    浏览(42)
  • NextJS开发:封装shadcn/ui中的AlertDialog确认对话框

    shadcn/ui很灵活可以方便的自己修改class样式,但是仅仅一个确认删除弹窗,需要拷贝太多代码和导入太多包,重复的代码量太多,不利于代码维护。所以进一步封装以符合项目中使用。 封装cx-alert-dialog.tsx custom-button.tsx 使用CxAlertDialog组件

    2024年02月04日
    浏览(44)
  • nextjs中beforePopState使用

    在某些情况下,希望监听popstate并在路由器对其进行操作之前执行某些操作。可以使用beforePopState。 在Next.js中,beforePopState是一个可选的生命周期函数,用于在浏览器的历史记录发生更改之前执行一些操作。具体来说,beforePopState会在用户点击浏览器的后退或前进按钮时触发。

    2024年01月25日
    浏览(35)
  • 网站开发[1] - Spring Boot 快速建立项目

    学校的数据库课程要求做出前端页面对数据库进行交互, 可以使用 Python 或者 Java 语言作为后端, Python语言使用起来非常方便, 但出于对自己的挑战以及更加贴合实际企业开发, 我选择使用 Java 语言进行开发. 搜遍了整个网络, 发现一些快速上手的教程都是不靠谱或者过时的, 耗费

    2024年02月08日
    浏览(42)
  • Python小白如何利用GPT4快速开发一个网站!

    这个是一个全栈的项目,麻雀虽小,五脏俱全! 全程都是利用gpt4进行辅助编程搞定的。第一版其实非常快,大概30分钟就搞定了,后续就是不断的添砖加瓦,增加功能和优化UI。 其实很多小白都在说要学Python,也想学Python,但是基本买了一本厚厚的书或者拿了一份资料之后就

    2024年02月09日
    浏览(37)
  • (二) 盘古UI,全网独创,较为全面的自定义Android UI框架,绝对帮助你快速开发!(盘古导航栏-PanguNavBar)

    (二) 盘古UI,较为全面的自定义UI框架,帮助你绝对的快速开发!(长期维护中) demo地址,点击查看github 1, 样例展示图 2, 介绍 个性化导航栏,标题栏,可以灵活设置和配置各种属性和事件! 下面直接上属性列表: attr 属性 对应的方法 method 介绍 introduction pangu_title_mid setMidTitle(String title)

    2024年04月14日
    浏览(47)
  • 使用nextjs本地化部署AI大模型gemma

    博主是AI新手,如有不对还请评论区指教~ 这里介绍mac的部署方式,win也可以实现。 本案例使用到:ollama + nextjs + langchain.js + milvus 来实现知识库问答和聊天。 ollama: 本地运行模型服务 nextjs: 前端框架项目 langchain.js: 调用模型服务并对话 milvus: 向量数据库 开源代码:G

    2024年04月13日
    浏览(62)
  • python使用flask实现前后端分离&通过前端修改数据库数据【全栈开发基础】

    完整代码放到了最后,时间紧张的话直接拉到最后或点击目录【🥩 完整代码】看完整代码 这里先提一下,我们运行后端代码之前需要先建立一个名字为 python 的数据库,而后在该数据库下创建表 userinfo ,因为看到有的朋友后端代码拿过去后会运行不起来或者就是直接报错了

    2023年04月09日
    浏览(41)
  • nextjs构建服务端渲染,同时使用Material UI进行项目配置

    使用create-next-app来启动一个新的Next.js应用,它会自动为你设置好一切 运行命令: 执行结果如下:   启动项目: 执行结果:  启动成功!  根据Material UI官网介绍,截至2021年底,样式组件与服务器渲染的材质UI项目不兼容。这是因为babel-plugin风格的组件不能与@mui包中的style

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包